1 PACKAGE BODY cs_kb_conc_prog_pkg AS
2 /* $Header: csksynib.pls 120.2 2005/11/11 17:27:06 klou noship $ */
3
4 /* errbuf = err messages
5 retcode = 0 SUCCESS, 1 = warning, 2=error
6 */
7
8 /* bmode: S = sync OFAST=optimize fast, OFULL = optimize full,
9 R = REBUILD, DR = DROP/Recreate
10 */
11
12 -- **********************
13 -- PRIVATE DECLARATIONS
14 -- **********************
15
16 invalid_mode_error EXCEPTION;
17 invalid_action_error EXCEPTION;
18 drop_index_error EXCEPTION;
19 create_index_error EXCEPTION;
20 rebuild_cache_error EXCEPTION;
21
22 g_cs_short_name VARCHAR2(10) := UPPER('CS'); -- set at patching
23 g_apps_short_name VARCHAR2(10) := UPPER('APPS'); -- set at patching
24 -- New for bug 4321268
25 G_BATCH_SIZE NUMBER := 10000;
26
27 -- New internal procedures for bug 4321268
28 /*
29 * Populate solution text index.
30 *
31 */
32 PROCEDURE populate_set_index (
33 x_msg_error OUT NOCOPY VARCHAR2,
34 x_return_status OUT NOCOPY VARCHAR2
35 )
36 IS
37 CURSOR all_published_solutions IS
38 SELECT tl.rowid -- tl.set_id
39 FROM cs_kb_sets_tl tl, cs_kb_sets_b b
40 WHERE b.set_id = tl.set_id
41 AND b.status = 'PUB';
42
43
44 TYPE l_rowid_type IS TABLE OF ROWID INDEX BY BINARY_INTEGER;
45 l_rowid_list l_rowid_type;
46
47 l_soln_comp_index VARCHAR2(250) := 'CS_KB_SETS_TL_N3';
48
49 BEGIN
50 x_return_status := fnd_api.G_RET_STS_SUCCESS;
51
52 -- Fetch out the list of IDs for all published solutions
53 OPEN all_published_solutions;
54 LOOP
55 FETCH all_published_solutions BULK COLLECT INTO l_rowid_list limit G_BATCH_SIZE;
56 FORALL i IN l_rowid_list.FIRST..l_rowid_list.LAST
57 UPDATE cs_kb_sets_tl
58 SET composite_assoc_index = 'R'
59 -- ,last_update_date = SYSDATE --- do not checkin updating last_update_date
60 WHERE rowid = l_rowid_list(i);
61
62 COMMIT;
63 /*
64 -- click off the sync. program
65 launch_sync_request(
66 p_mode => 'S',
67 p_conc_request_name => 'CS_KB_SYNC_SOLUTIONS_INDEX',
68 x_msg_error => x_msg_error,
69 x_return_status => x_return_status );
70
71 IF x_return_status != fnd_api.G_RET_STS_SUCCESS THEN
72 EXIT;
73 END IF;
74
75 x_return_status := fnd_api.G_RET_STS_SUCCESS;
76 */
77
78 -- Check if all_published_solutions is notfound.
79 -- NOTE: this check should come at the end because for the last batch
80 -- the total number of sets being fetched may be less than the l_batch_size.
81 -- If l_set_id_list is not filled with the exact number as the l_batch_size,
82 -- all_published_solutons%notfound is true. Putting this at the end
83 -- guarantees we process the last batch.
84 EXIT WHEN all_published_solutions%NOTFOUND;
85 END LOOP;
86 CLOSE all_published_solutions;
87
88 Sync_index( l_soln_comp_index, 'S', 0 );
89
90 EXCEPTION
91 WHEN OTHERS THEN
92 ROLLBACK; -- do not use savepoint because savepoint is cleared when commit.
93 x_msg_error := 'populate_set_index: '
94 ||fnd_message.GET_STRING('CS','CS_KB_C_UNEXP_ERR')||' '||SQLERRM;
95 x_return_status := fnd_api.G_RET_STS_ERROR;
96 END populate_set_index;
97
98 /*
99 * Populate element text index.
100 *
101 */
102 PROCEDURE populate_element_index (
103 x_msg_error OUT NOCOPY VARCHAR2,
104 x_return_status OUT NOCOPY VARCHAR2
105 )
106 IS
107 l_statement_comp_index VARCHAR2(250) := 'CS_KB_ELEMENTS_TL_N2';
108 BEGIN
109 x_return_status := fnd_api.G_RET_STS_SUCCESS;
110
111 SAVEPOINT populate_element_index_SAV;
112
113 -- We do not use bulk update in this case because the concurrent request
114 -- is incompatbile with itself. Even we kick off the sync. request, it
115 -- will be in pending status until "DR" or "R" request is finished. So,
116 UPDATE /*+ parallel(t) */ cs_kb_elements_tl t
117 SET t.composite_text_index = 'B';
118
119 COMMIT;
120
121 -- Reestablish savepoint, as commit cleared it.
122 SAVEPOINT populate_element_index_SAV;
123
124 -- Start synchronizing index.
125 Sync_index( l_statement_comp_index, 'S', 0 );
126
127 EXCEPTION
128 WHEN OTHERS THEN
129 ROLLBACK TO populate_element_index_SAV;
130 x_msg_error := 'populate_element_index: '
131 ||fnd_message.GET_STRING('CS','CS_KB_C_UNEXP_ERR')||' '||SQLERRM;
132 x_return_status := fnd_api.G_RET_STS_ERROR;
133 END populate_element_index;
134
135
136 /*
137 * Populate soluton categories text index.
138 *
139 */
140 PROCEDURE populate_soln_cat_index (
141 x_msg_error OUT NOCOPY VARCHAR2,
142 x_return_status OUT NOCOPY VARCHAR2
143 )
144 IS
145 index1 VARCHAR2(250) := 'CS_KB_SOLN_CAT_TL_N1';
146
147 BEGIN
148 x_return_status := fnd_api.G_RET_STS_SUCCESS;
149 SAVEPOINT populate_soln_cat_index_SAV;
150 UPDATE /*+ parallel(t) */ cs_kb_soln_categories_tl t
151 SET t.name = t.name;
152
153 COMMIT;
154
155 -- reestablish savepoint after commit.
156 SAVEPOINT populate_soln_cat_index_SAV;
157
158 -- Start index synchronization
159 Sync_index( index1, 'S', 0 );
160
161 EXCEPTION
162 WHEN OTHERS THEN
163 ROLLBACK TO populate_soln_cat_index_SAV;
164 x_msg_error := 'populate_sol_cat_index: '
165 ||fnd_message.GET_STRING('CS','CS_KB_C_UNEXP_ERR')||' '||SQLERRM;
166 x_return_status := fnd_api.G_RET_STS_ERROR;
167 END populate_soln_cat_index;
168
169
170 /*
171 * Populate forum index.
172 *
173 */
174 PROCEDURE populate_forum_index (
175 x_msg_error OUT NOCOPY VARCHAR2,
176 x_return_status OUT NOCOPY VARCHAR2
177 )
178 IS
179 index3 VARCHAR2(250) := 'CS_FORUM_MESSAGES_TL_N4';
180 BEGIN
181 x_return_status := fnd_api.G_RET_STS_SUCCESS;
182
183 SAVEPOINT populate_forum_index_SAV;
184
185 UPDATE /*+ parallel(t) */ cs_forum_messages_tl t
186 SET t.composite_assoc_col = 'B';
187
188 COMMIT;
189
190 -- reestablish savepoint after commit
191 SAVEPOINT populate_forum_index_SAV;
192
193 -- Start index synchronization
194 Sync_index( index3, 'S', 0 );
195 EXCEPTION
196 WHEN OTHERS THEN
197 ROLLBACK TO populate_forum_index_SAV;
198 x_msg_error := 'populate_forum_index: '
199 ||fnd_message.GET_STRING('CS','CS_KB_C_UNEXP_ERR')||' '||SQLERRM;
200 x_return_status := fnd_api.G_RET_STS_ERROR;
201 END populate_forum_index;
202 -- 4321268_new_apis_eof
203 /*
204 * get_max_parallel_worker: get THE job_queue_processes value.
205 */
206 FUNCTION get_max_parallel_worker RETURN NUMBER
207 IS
208 l_worker NUMBER := 0;
209
210 -- 4321268
211 -- Fetch the correct paremeters to calculate max. parallel workers.
212 CURSOR get_param_value(p_name IN varchar2) IS
213 SELECT to_number(nvl(VALUE, 0))
214 FROM v$parameter
215 WHERE name = lower(p_name);
216
217 l_cpu_count NUMBER;
218 l_thread_per_cpu NUMBER;
219 -- 4321268_eof
220 BEGIN
221 --4321268
222 OPEN get_param_value('cpu_count');
223 FETCH get_param_value INTO l_cpu_Count;
224 CLOSE get_param_value;
225
226 OPEN get_param_value('parallel_threads_per_cpu');
227 FETCH get_param_value INTO l_thread_per_cpu;
228 CLOSE get_param_value;
229
230 -- SELECT to_number(nvl(VALUE, 0)) INTO l_worker FROM v$parameter
231 -- WHERE NAME = 'job_queue_processes';
232 l_worker := l_cpu_count * l_thread_per_cpu;
233 --4321268
234 RETURN l_worker;
235 EXCEPTION
236 WHEN OTHERS THEN
237 RETURN l_worker;
238 END;
239
240 /*
241 * is_validate_mode: VALIDATE a synchronization MODE.
242 * RETURN 'Y' IF THE MODE IS valid. Otherwise RETURN 'N'.
243 */
244 FUNCTION is_validate_mode(bmode IN VARCHAR2) RETURN VARCHAR
245 IS
246 l_valid_mode VARCHAR2(1) := 'Y';
247 l_mode VARCHAR2(10) := bmode;
248 BEGIN
249 IF l_mode NOT IN ('S', 'R', 'OFAST', 'OFULL', 'RC', 'DR' ) THEN
250 l_valid_mode := 'N';
251 END IF;
252 RETURN l_valid_mode;
253
254 END;
255
256 /*
257 * do_create
258 * This PROCEDURE executes THE CREATE command.
259 */
260 PROCEDURE do_create ( p_create_cmd IN VARCHAR2,
261 p_index_name IN VARCHAR2,
262 p_index_version IN VARCHAR2,
263 x_msg_error OUT NOCOPY VARCHAR2,
264 x_return_status OUT NOCOPY VARCHAR2
265 )
266 IS
267
268 l_update VARCHAR2(1) := 'Y';
269 BEGIN
270 -- initialize return status
271 x_return_status := fnd_api.G_RET_STS_ERROR;
272
273 EXECUTE IMMEDIATE p_create_cmd;
274
275 x_return_status := fnd_api.G_RET_STS_SUCCESS;
276 EXCEPTION
277 WHEN OTHERS THEN
278 x_msg_error := 'do_create: '||p_index_name||' :'
279 ||fnd_message.GET_STRING('CS','CS_KB_C_UNEXP_ERR')||' '||SQLERRM;
280 x_return_status := fnd_api.G_RET_STS_ERROR;
281 END do_create;
282
283
284 /*
285 * resolve_parallel_indexing
286 */
287 FUNCTION resolve_parallel_indexing (
288 p_create_cmd IN VARCHAR2,
289 p_worker IN NUMBER DEFAULT 0
290 ) RETURN VARCHAR
291 IS
292 l_cmd VARCHAR2(500) := p_create_cmd;
293 l_worker NUMBER := p_worker;
294 l_max_worker NUMBER := get_max_parallel_worker;
295
296 --3576867
297 l_db_version NUMBER := null;
298 l_compatibility VARCHAR2(100) := null;
299 l_db_version_str VARCHAR2(100) := null;
300 BEGIN
301 --3576867
302 If p_worker is null Then
303 l_worker := 0;
304 End If;
305
306 DBMS_UTILITY.db_version(l_db_version_str, l_compatibility);
307 If l_db_version_str is null Then
308 l_db_version := 8;
309 Else
310 l_db_version := to_number(substr(l_db_version_str, 1,
311 (instr(l_db_version_str, '.'))-1));
312 End If;
313
314 If l_db_version Is Not Null Then
315 If l_db_version > 8 Then
316 IF l_worker > l_max_worker THEN
317 l_worker := l_max_worker;
318 END IF;
319 End if; -- l_db_version eof
320 Else
321 l_worker := 0;
322 End If;
323 -- 3576867 eof
324
325 IF l_worker > 0 THEN
326 l_cmd := l_cmd || ' parallel '||TO_CHAR(l_worker);
327 END IF;
328
329 RETURN l_cmd;
330 EXCEPTION
331 WHEN OTHERS THEN
332 -- any errors: do not append anything.
333 RETURN p_create_cmd;
334 END resolve_parallel_indexing;
335
336 -- ************************
337 -- PUBLIC IMPLEMENTATIONS
338 -- ************************
339
340 PROCEDURE Sync_index( index1 IN VARCHAR2,
341 bmode IN VARCHAR2,
342 pworker IN NUMBER DEFAULT 0)
343 IS
344 l_index_name VARCHAR2(300) := g_cs_short_name||'.'||index1;
345
346 BEGIN
347
348 IF bmode = 'S' THEN
349 AD_CTX_DDL.sync_index( l_index_name );
350 ELSIF bmode = 'OFAST' THEN
351 AD_CTX_DDL.OPTIMIZE_INDEX( l_index_name, CTX_DDL.OPTLEVEL_FAST, NULL, NULL );
352 ELSIF bmode = 'OFULL' THEN
353 AD_CTX_DDL.OPTIMIZE_INDEX( l_index_name, CTX_DDL.OPTLEVEL_FULL, NULL, NULL );
354 ELSIF bmode = 'R' THEN
355 -- 4321268: rebuild in parallel mode always. Serial online mode,
356 -- is taking care in the individual index program.
357 IF pworker IS NOT NULL AND pworker > 0 THEN
358
359 EXECUTE IMMEDIATE 'alter index ' || l_index_name ||' REBUILD parallel '|| to_char(pworker);
360 END IF;
361 -- 4321268_eof
362 ELSIF bmode = 'DR' THEN
363 -- logic to drop or create is taken in the individual api.
364 NULL;
365 ELSE
366 FND_FILE.PUT_LINE(FND_FILE.LOG,
367 fnd_message.get_string('CS', 'CS_KB_SYN_INDEX_INV_MODE'));
368 RAISE invalid_mode_error;
369 END IF;
370 END Sync_index;
371
372
373 /*
374 * Sync_All_index: synchronize ALL KM indices IN serial MODE.
375 * Deprecated since 11.5.10.
376 */
377 PROCEDURE Sync_All_Index (ERRBUF OUT NOCOPY VARCHAR2,
378 RETCODE OUT NOCOPY NUMBER,
379 BMODE IN VARCHAR2 DEFAULT NULL)
380 IS
381 BEGIN
382
383 -- Return successfully
384 errbuf := fnd_message.get_string('CS', 'CS_KB_C_SUCCESS');
385 retcode :=0;
386 END Sync_All_Index;
387
388 /*
389 * Create_Set_Index
390 * This PROCEDURE creates THE solution INDEX AND also populates THE INDEX
391 * content.
392 */
393 PROCEDURE Create_Set_Index
394 ( pworker IN NUMBER DEFAULT 0,
395 x_msg_error OUT NOCOPY VARCHAR2,
396 x_return_status OUT NOCOPY VARCHAR2
397 )
398 IS
399 l_create_cmmd VARCHAR2(500):= NULL;
400 l_index_version VARCHAR2(15) := '115.10.1';
401 l_index_name VARCHAR2(30) := 'cs_kb_sets_tl_N3';
402
403 BEGIN
404
405 l_create_cmmd :=
406 ' CREATE INDEX '||g_cs_short_name||'.'||l_index_name||' on '
407 || g_cs_short_name||'.cs_kb_sets_tl(composite_assoc_index) '
408 || ' INDEXTYPE IS ctxsys.context '
409 || ' parameters (''datastore '||g_apps_short_name||'.CS_KB_COMPOSITE_ELES '
410 || ' section group '||g_apps_short_name||'.CS_KB_BASIC_GRP '
411 || ' lexer '||g_apps_short_name||'.CS_KB_GLOBAL_LEXER language column SOURCE_LANG '
412 || ' wordlist '||g_apps_short_name||'.CS_KB_FUZZY_PREF '
413 --4321268
414 || ' storage ' ||g_apps_short_name||'.CS_KB_INDEX_STORAGE '; -- <-command not yet completed
415 -- 4321268_eof
416
417 x_return_status := fnd_api.G_RET_STS_ERROR;
418
419 -- 4321268
420 IF nvl(pworker,0) = 0 THEN
421 -- Create index online
422 -- 1. Create index without populate
423 l_create_cmmd := l_create_cmmd || ' nopopulate '') ';
424 ELSE
425 l_create_cmmd := l_create_cmmd || ''')';
426 l_create_cmmd := resolve_parallel_indexing(l_create_cmmd, pworker);
427 END IF;
428
429 -- 4321268_eof
430 do_create(
431 p_create_cmd => l_create_cmmd,
432 p_index_name => l_index_name,
433 p_index_version => l_index_version,
434 x_msg_error => x_msg_error,
435 x_return_status => x_return_status );
436
437 IF x_return_status <> fnd_api.G_RET_STS_SUCCESS THEN
438 RAISE create_index_error;
439 END IF;
440
441 -- 4321268
442 IF nvl(pworker, 0) = 0 THEN
443 populate_set_index (
444 x_msg_error ,
445 x_return_status
446 );
447 END IF;
448 IF x_return_status <> fnd_api.G_RET_STS_SUCCESS THEN
449 RAISE create_index_error;
450 END IF;
451 -- 4321268_eof
452
453
454 x_return_status := fnd_api.G_RET_STS_SUCCESS;
455
456 EXCEPTION
457 WHEN create_index_error THEN
458 NULL; -- x_msg_error is set in the do_create api.
459 WHEN others THEN
460 x_msg_error := 'Create_Set_Index: '
461 ||fnd_message.GET_STRING('CS','CS_KB_C_UNEXP_ERR')||' '||SQLERRM;
462 END Create_Set_Index;
463
464
465 /*
466 * Create_Element_Index
467 * This PROCEDURE creates THE STATEMENT INDEX AND also populates THE INDEX
468 * content.
469 */
470 PROCEDURE Create_Element_Index
471 ( pworker IN NUMBER DEFAULT 0,
472 x_msg_error OUT NOCOPY VARCHAR2,
473 x_return_status OUT NOCOPY VARCHAR2
474 )
475 IS
476 l_create_cmmd VARCHAR2(500):= NULL;
477
478 l_index_version VARCHAR2(15) := '115.10.1';
479 l_index_name VARCHAR2(30) := 'cs_kb_elements_tl_N2';
480 BEGIN
481 l_create_cmmd :=
482 ' CREATE INDEX '||g_cs_short_name||'.cs_kb_elements_tl_N2 on '
483 ||g_cs_short_name||'.cs_kb_elements_tl(composite_text_index) '
484 ||' INDEXTYPE IS ctxsys.context '
485 ||' parameters (''datastore '||g_apps_short_name||'.CS_KB_ELES '
486 ||' section group '||g_apps_short_name||'.CS_KB_BASIC_GRP '
487 ||' lexer '||g_apps_short_name||'.CS_KB_GLOBAL_LEXER language column SOURCE_LANG '
488 ||' wordlist '||g_apps_short_name||'.CS_KB_FUZZY_PREF '
489 --4321268
490 || ' storage ' ||g_apps_short_name||'.CS_KB_INDEX_STORAGE '; -- <-command not yet completed
491 -- 4321268_eof
492
493 x_return_status := fnd_api.G_RET_STS_ERROR;
494
495 -- 4321268
496 IF nvl(pworker,0) = 0 THEN
497 -- Create index online
498 -- 1. Create index without populate
499 l_create_cmmd := l_create_cmmd || ' nopopulate '') ';
500 ELSE
501 l_create_cmmd := l_create_cmmd || ''')';
502 l_create_cmmd := resolve_parallel_indexing(l_create_cmmd, pworker);
503
504 END IF;
505 -- 4321268_eof
506
507 do_create
508 ( p_create_cmd => l_create_cmmd,
509 p_index_name => l_index_name,
510 p_index_version => l_index_version,
511 x_msg_error => x_msg_error,
512 x_return_status => x_return_status
513 );
514
515 -- 4321268
516 IF nvl(pworker, 0) = 0 THEN
517 populate_element_index (
518 x_msg_error ,
519 x_return_status
520 );
521 END IF;
522 IF x_return_status <> fnd_api.G_RET_STS_SUCCESS THEN
523 RAISE create_index_error;
524 END IF;
525 -- 4321268_eof
526
527 IF x_return_status <> fnd_api.G_RET_STS_SUCCESS THEN
528 RAISE create_index_error;
529 END IF;
530 x_return_status := fnd_api.G_RET_STS_SUCCESS;
531
532 EXCEPTION
533 WHEN create_index_error THEN
534 NULL; -- x_msg_error is set in the do_create api.
535 WHEN others THEN
536 x_msg_error := 'Create_Element_Index: '
537 ||fnd_message.GET_STRING('CS','CS_KB_C_UNEXP_ERR')||' '||SQLERRM;
538 END Create_Element_Index;
539
540
541 /*
542 * Create_Soln_Cat_Index
543 * This PROCEDURE creates THE CATEGORY INDEX AND also populates THE INDEX
544 * content.
545 */
546 PROCEDURE Create_Soln_Cat_Index
547 ( pworker IN NUMBER DEFAULT 0,
548 x_msg_error OUT NOCOPY VARCHAR2,
549 x_return_status OUT NOCOPY VARCHAR2
550 )
551 IS
552 l_create_cmmd VARCHAR2(500):= NULL;
553 l_index_version VARCHAR2(15) := '115.10.1';
554 l_index_name VARCHAR2(30) := 'CS_KB_SOLN_CAT_TL_N1';
555
556 BEGIN
557 l_create_cmmd :=
558 ' CREATE INDEX '||g_cs_short_name||'.CS_KB_SOLN_CAT_TL_N1 on '
559 ||g_cs_short_name||'.cs_kb_soln_categories_tl(name) '
560 ||' INDEXTYPE IS ctxsys.context '
561 ||' parameters ('' '
562 ||' lexer '||g_apps_short_name||'.CS_KB_GLOBAL_LEXER language column SOURCE_LANG '
563 ||' wordlist '||g_apps_short_name||'.CS_KB_FUZZY_PREF '
564 --4321268
565 || ' storage ' ||g_apps_short_name||'.CS_KB_INDEX_STORAGE '; -- <-command not yet completed
566 -- 4321268_eof
567
568 x_return_status := fnd_api.G_RET_STS_ERROR;
569
570 -- 4321268
571 IF nvl(pworker,0) = 0 THEN
572 -- Create index online
573 -- 1. Create index without populate
574 l_create_cmmd := l_create_cmmd || ' nopopulate '') ';
575 ELSE
576
577 l_create_cmmd := l_create_cmmd || ''')';
578 l_create_cmmd := resolve_parallel_indexing(l_create_cmmd, pworker);
579
580 END IF;
581 -- 4321268_eof
582
583 do_create
584 ( p_create_cmd => l_create_cmmd,
585 p_index_name => l_index_name,
586 p_index_version => l_index_version,
587 x_msg_error => x_msg_error,
588 x_return_status => x_return_status
589 );
590
591 -- 4321268
592 IF nvl(pworker, 0) = 0 THEN
593 populate_soln_cat_index (
594 x_msg_error ,
595 x_return_status
596 );
597 END IF;
598 IF x_return_status <> fnd_api.G_RET_STS_SUCCESS THEN
599 RAISE create_index_error;
600 END IF;
601 -- 4321268_eof
602 x_return_status := fnd_api.G_RET_STS_SUCCESS;
603
604 EXCEPTION
605 WHEN create_index_error THEN
606 NULL; -- x_msg_error is set in the do_create api.
607 WHEN others THEN
608 x_msg_error := 'Create_Element_Index: '
609 ||fnd_message.GET_STRING('CS','CS_KB_C_UNEXP_ERR')||' '||SQLERRM;
610 END Create_Soln_Cat_Index;
611
612 /*
613 * Create_Forum_Index
614 * This PROCEDURE creates THE forum INDEX AND also populates THE INDEX
615 * content.
616 */
617 PROCEDURE Create_Forum_Index
618 ( pworker IN NUMBER DEFAULT 0,
619 x_msg_error OUT NOCOPY VARCHAR2,
620 x_return_status OUT NOCOPY VARCHAR2
621 )
622 IS
623 l_create_cmmd VARCHAR2(500):= NULL;
624
625 l_index_version VARCHAR2(15) := '115.10.1';
626 l_index_name VARCHAR2(30) := 'cs_forum_messages_tl_n4';
627 BEGIN
628 l_create_cmmd :=
629 'create index '||g_cs_short_name||'.cs_forum_messages_tl_n4 '
630 || 'on '||g_cs_short_name||'.cs_forum_messages_tl(composite_assoc_col) '
631 || 'indextype is ctxsys.context parameters( '''
632 || 'datastore '||g_apps_short_name||'.CS_FORUM_MESG_ELES '
633 || ' section group '||g_apps_short_name||'.CS_KB_BASIC_GRP '
634 || 'lexer '||g_apps_short_name||'.CS_KB_GLOBAL_LEXER language column SOURCE_LANG '
635 || 'wordlist '||g_apps_short_name||'.CS_KB_FUZZY_PREF '
636 --4321268
637 || ' storage ' ||g_apps_short_name||'.CS_KB_INDEX_STORAGE '; -- <-command not yet completed
638 -- 4321268_eof
639
640 x_return_status := fnd_api.G_RET_STS_ERROR;
641
642 -- 4321268
643 IF nvl(pworker,0) = 0 THEN
644 -- Create index online
645 -- 1. Create index without populate
646 l_create_cmmd := l_create_cmmd || ' nopopulate '') ';
647 ELSE
648 l_create_cmmd := l_create_cmmd || ''')';
649 l_create_cmmd := resolve_parallel_indexing(l_create_cmmd, pworker);
650
651 END IF;
652 -- 4321268_eof
653
654 do_create
655 ( p_create_cmd => l_create_cmmd,
656 p_index_name => l_index_name,
657 p_index_version => l_index_version,
658 x_msg_error => x_msg_error,
659 x_return_status => x_return_status
660 );
661
662 -- 4321268
663 IF nvl(pworker, 0) = 0 THEN
664 populate_forum_index (
665 x_msg_error ,
666 x_return_status
667 );
668 END IF;
669 IF x_return_status <> fnd_api.G_RET_STS_SUCCESS THEN
670 RAISE create_index_error;
671 END IF;
672 -- 4321268_eof
673 x_return_status := fnd_api.G_RET_STS_SUCCESS;
674
675 EXCEPTION
676 WHEN create_index_error THEN
677 NULL; -- x_msg_error is set in the do_create api.
678 WHEN others THEN
679 x_msg_error := 'Create_Forum_Index: '
680 ||fnd_message.GET_STRING('CS','CS_KB_C_UNEXP_ERR')||' '||SQLERRM;
681 END Create_Forum_Index;
682
683
684
685 PROCEDURE Drop_Index
686 ( p_index_name IN VARCHAR,
687 x_msg_error OUT NOCOPY VARCHAR2,
688 x_return_status OUT NOCOPY VARCHAR2
689 )
690 IS
691 drop_index VARCHAR2(100) := NULL;
692
693 CURSOR get_index_cursor(p_index_name VARCHAR2, p_owner VARCHAR2) IS
694 SELECT COUNT(*) FROM dba_indexes
695 WHERE index_name = UPPER(p_index_name)
696 AND owner= UPPER(p_owner);
697
698 l_total NUMBER := 0;
699
700 BEGIN
701 x_return_status := fnd_api.G_RET_STS_ERROR;
702 IF p_index_name IS NULL THEN
703 RETURN;
704 END IF;
705
706 -- If only if the index exists:
707 OPEN get_index_cursor(p_index_name, g_cs_short_name);
708 FETCH get_index_cursor INTO l_total;
709 CLOSE get_index_cursor;
710
711 IF l_total > 0 THEN
712 drop_index := 'drop index '||g_cs_short_name||'.'||p_index_name||' force ';
713 EXECUTE IMMEDIATE drop_index;
714 END IF;
715
716 x_return_status := fnd_api.G_RET_STS_SUCCESS;
717
718 -- Logic to remove the index version in the
719 -- global system table.
720 EXCEPTION
721 WHEN others THEN
722 x_msg_error := 'Drop_Index: '||
723 fnd_message.GET_STRING('CS','CS_KB_C_UNEXP_ERR')||' '||
724 SQLERRM;
725 END Drop_Index;
726
727
728 /*
729 * Sync_Set_Index
730 * This PROCEDURE syncs THE Oracle Text INDEX FOR KM Solutions TO
731 * bring THE INDEX up-TO-DATE.
732 */
733 PROCEDURE Sync_Set_Index
734 ( errbuf OUT NOCOPY VARCHAR2,
735 retcode OUT NOCOPY NUMBER,
736 bmode IN VARCHAR2,
737 pworker IN NUMBER DEFAULT 0)
738 IS
739 CURSOR delay_marked_solns_batch_csr( c_batch_size NUMBER ) IS
740 SELECT set_id
741 FROM cs_kb_sets_b
742 -- 3679483
743 -- WHERE reindex_flag = 'Y'
744 WHERE reindex_flag = 'U'
745 -- 3679483 eof
746 AND ROWNUM <= c_batch_size;
747
748 l_solution_id NUMBER := 0;
749 l_soln_comp_index VARCHAR2(250) := 'CS_KB_SETS_TL_N3';
750 l_num_batch_rows_updated NUMBER := 0;
751 l_reindex_batch_size NUMBER := 300;
752 l_mode VARCHAR2(10) := bmode;
753
754 l_return_status VARCHAR2(1) := fnd_api.G_RET_STS_ERROR;
755 BEGIN
756
757 -- Initialize some variables
758 retcode := 2; -- init return val to FAIL
759
760 IF l_mode IS NULL THEN
761 l_mode := 'S';
762 END IF;
763
764 IF is_validate_mode(l_mode) = 'N' THEN
765 RAISE invalid_mode_error;
766 END IF;
767
768 -- check whether it is 'DR'
769 IF l_mode = 'DR' THEN
770 -- At this point we can assume that we can safely drop the index.
771 Drop_Index(l_soln_comp_index,
772 errbuf,
773 l_return_status);
774 IF l_return_status <> fnd_api.G_RET_STS_SUCCESS THEN
775 RAISE drop_index_error;
776 END IF;
777
778 Create_Set_Index(pworker,
779 errbuf,
780 l_return_status);
781 IF l_return_status <> fnd_api.G_RET_STS_SUCCESS THEN
782 RAISE create_index_error;
783 END IF;
784 ELSIF l_mode = 'RC' THEN
785 -- Rebuild content cache
786 Rebuild_Soln_Content_Cache( errbuf, retcode );
787 IF retcode <> 0 THEN
788 RAISE rebuild_cache_error;
789 END IF;
790 ELSE
791 fnd_profile.get('CS_KB_REINDEX_BATCH_SIZE', l_reindex_batch_size);
792 IF ( l_reindex_batch_size IS NULL ) THEN
793 l_reindex_batch_size := 300;
794 END IF;
795
796 -- Sync the composite solution index up-front.
797 -- This will bring any solutions already marked for reindexing
798 -- up-to date and make them searchable.
799 -- 4321268
800 IF (pworker IS NULL OR pworker = 0) AND l_mode = 'R' THEN
801 populate_set_index (
802 x_msg_error => errbuf,
803 x_return_status => l_return_status
804 );
805 Else
806 Sync_index( l_soln_comp_index, l_mode, PWORKER );
807 END IF;
808 -- 4321268_eof
809
810 -- Query up solutions that have been delay-marked for reindexing.
811 -- Loop through these solutions in batches (batch size defined by
812 -- profile option) and transfer the delay-mark to immediate mark.
813 -- After the mark transfer for each of these batches, sync the index
814 -- to make the batch of solutions searchable.
815 LOOP
816 l_num_batch_rows_updated := 0;
817
818 OPEN delay_marked_solns_batch_csr( l_reindex_batch_size );
819 LOOP
820 FETCH delay_marked_solns_batch_csr INTO l_solution_id;
821 -- Exit inner loop when there are no more delay-marked
822 -- statements in the batch
823 EXIT WHEN delay_marked_solns_batch_csr%NOTFOUND;
824
825 -- Immediately mark the solution composite text index column
826 UPDATE cs_kb_sets_tl
827 SET composite_assoc_index = 'U'
828 WHERE set_id = l_solution_id;
829
830 -- Clear the delayed index mark on the solution
831 UPDATE cs_kb_sets_b
832 SET reindex_flag = NULL
833 WHERE set_id = l_solution_id;
834
835 l_num_batch_rows_updated := l_num_batch_rows_updated + 1;
836 END LOOP;
837 CLOSE delay_marked_solns_batch_csr;
838 COMMIT;
839
840 -- Exit outer loop when there are no more rows to update
841 EXIT WHEN l_num_batch_rows_updated = 0;
842
843 -- Otherwise sync the index and loop again for the next batch
844 Sync_index( l_soln_comp_index, l_mode, PWORKER );
845
846 END LOOP;
847 END IF; -- l_mode check
848
849 -- klou (SRCHEFF)
850 -- Update magic word.
851 Update_Magic_Word;
852
853 -- Set return value and log message to Success
854 errbuf := fnd_message.get_string('CS', 'CS_KB_C_SUCCESS');
855 retcode := 0;
856
857 EXCEPTION
858 WHEN invalid_mode_error THEN
859 BEGIN
860 errbuf := fnd_message.get_string('CS', 'CS_KB_SYN_INDEX_INV_MODE');
861 END;
862 WHEN drop_index_error THEN
863 BEGIN
864 FND_FILE.PUT_LINE(FND_FILE.LOG, errbuf);
865 EXCEPTION
866 WHEN others THEN
867 NULL;
868 END;
869 WHEN create_index_error THEN
870 BEGIN
871 FND_FILE.PUT_LINE(FND_FILE.LOG, errbuf);
872 EXCEPTION
873 WHEN others THEN
874 NULL;
875 END;
876 WHEN others THEN
877 errbuf := 'Sync_Set_Index: '||
878 fnd_message.GET_STRING('CS','CS_KB_C_UNEXP_ERR')||' '||
879 SQLERRM;
880 -- Write out error to concurrent program log
881 BEGIN
882 FND_FILE.PUT_LINE(FND_FILE.LOG, errbuf);
883 EXCEPTION
884 WHEN others THEN
885 NULL;
886 END;
887
888 END Sync_Set_Index;
889
890
891
892 /*
893 * Sync_Element_Index
894 * This PROCEDURE syncs THE Oracle Text INDEX FOR KM Statements TO
895 * bring THE INDEX up-TO-DATE.
896 */
897 PROCEDURE Sync_Element_Index
898 ( ERRBUF OUT NOCOPY VARCHAR2,
899 RETCODE OUT NOCOPY NUMBER,
900 BMODE IN VARCHAR2,
901 pworker IN NUMBER DEFAULT 0)
902 IS
903 CURSOR delay_marked_stmts_batch_csr( c_batch_size NUMBER ) IS
904 SELECT element_id
905 FROM cs_kb_elements_b
906 -- 3679483
907 -- WHERE reindex_flag = 'Y'
908 WHERE reindex_flag = 'U'
909 -- 3679483 eof
910 AND ROWNUM <= c_batch_size;
911
912 l_statement_id NUMBER := 0;
913 l_statement_comp_index VARCHAR2(250) := 'CS_KB_ELEMENTS_TL_N2';
914 l_num_batch_rows_updated NUMBER := 0;
915 l_reindex_batch_size NUMBER := 300;
916 l_mode VARCHAR2(10) := bmode;
917 l_return_status VARCHAR2(1) := fnd_api.G_RET_STS_ERROR;
918 BEGIN
919 -- Initialize some variables
920 retcode := 2; -- init return val to FAIL
921
922 IF l_mode IS NULL THEN
923 l_mode := 'S';
924 END IF;
925
926 IF is_validate_mode(l_mode) = 'N' THEN
927 RAISE invalid_mode_error;
928 END IF;
929
930 -- check whether it is 'DR'
931 IF l_mode = 'DR' THEN
932 -- At this point we can assume that we can safely drop the index.
933 Drop_Index(l_statement_comp_index,
934 errbuf,
935 l_return_status);
936 IF l_return_status <> fnd_api.G_RET_STS_SUCCESS THEN
937 RAISE drop_index_error;
938 END IF;
939
940 Create_Element_Index(pworker,
941 errbuf,
942 l_return_status);
943 IF l_return_status <> fnd_api.G_RET_STS_SUCCESS THEN
944 RAISE create_index_error;
945 END IF;
946 ELSE
947 fnd_profile.get('CS_KB_REINDEX_BATCH_SIZE', l_reindex_batch_size);
948 IF ( l_reindex_batch_size IS NULL ) THEN
949 l_reindex_batch_size := 300;
950 END IF;
951
952 -- Sync the composite statement index up-front.
953 -- This will bring any statement already marked for reindexing
954 -- up-to date and make them searchable.
955 -- 4321268
956 IF (pworker IS NULL OR pworker = 0) AND l_mode = 'R' THEN
957 populate_element_index (
958 x_msg_error => errbuf,
959 x_return_status => l_return_status
960 );
961 ELSE
962 Sync_index( l_statement_comp_index, bmode, PWORKER );
963 END IF;
964 -- 4321268_eof
965 -- Query up statements that have been delay-marked for reindexing.
966 -- Loop through these statements in batches (batch size defined by
967 -- profile option) and transfer the delay-mark to immediate mark.
968 -- After the mark transfer for each of these batches, sync the index
969 -- to make the batch of statements searchable.
970 LOOP
971 l_num_batch_rows_updated := 0;
972
973 OPEN delay_marked_stmts_batch_csr( l_reindex_batch_size );
974 LOOP
975 FETCH delay_marked_stmts_batch_csr INTO l_statement_id;
976 -- Exit inner loop when there are no more delay-marked
977 -- statements in the batch
978 EXIT WHEN delay_marked_stmts_batch_csr%NOTFOUND;
979
980 -- Immediately mark the statement composite text index column
981 UPDATE cs_kb_elements_tl
982 SET composite_text_index = 'U'
983 WHERE element_id = l_statement_id;
984
985 -- Clear the delayed index mark on the statement
986 UPDATE cs_kb_elements_b
987 SET reindex_flag = NULL
988 WHERE element_id = l_statement_id;
989
990 l_num_batch_rows_updated := l_num_batch_rows_updated + 1;
991 END LOOP;
992 CLOSE delay_marked_stmts_batch_csr;
993 COMMIT;
994
995 -- Exit outer loop when there are no more rows to update
996 EXIT WHEN l_num_batch_rows_updated = 0;
997
998 -- Otherwise sync the index and loop again for the next batch
999 Sync_index( l_statement_comp_index, bmode );
1000
1001 END LOOP;
1002 END IF;
1003 -- Set return value and log message to Success
1004 errbuf := fnd_message.get_string('CS', 'CS_KB_C_SUCCESS');
1005 retcode := 0;
1006
1007 EXCEPTION
1008 WHEN invalid_mode_error THEN
1009 BEGIN
1010 errbuf := fnd_message.get_string('CS', 'CS_KB_SYN_INDEX_INV_MODE');
1011 END;
1012 WHEN drop_index_error THEN
1013 BEGIN
1014 FND_FILE.PUT_LINE(FND_FILE.LOG, errbuf);
1015 EXCEPTION
1016 WHEN others THEN
1017 NULL;
1018 END;
1019 WHEN create_index_error THEN
1020 BEGIN
1021 FND_FILE.PUT_LINE(FND_FILE.LOG, errbuf);
1022 EXCEPTION
1023 WHEN others THEN
1024 NULL;
1025 END;
1026 WHEN others THEN
1027 errbuf := 'Sync_Element_Index: '||
1028 fnd_message.GET_STRING('CS','CS_KB_C_UNEXP_ERR')||' '||
1029 SQLERRM;
1030 -- Write out error to concurrent program log
1031 BEGIN
1032 FND_FILE.PUT_LINE(FND_FILE.LOG, errbuf);
1033 EXCEPTION
1034 WHEN others THEN
1035 NULL;
1036 END;
1037 END Sync_Element_Index;
1038
1039
1040 PROCEDURE Sync_Forum_Index(ERRBUF OUT NOCOPY VARCHAR2,
1041 RETCODE OUT NOCOPY NUMBER,
1042 BMODE IN VARCHAR2,
1043 pworker IN NUMBER DEFAULT 0)
1044
1045 IS
1046 index3 VARCHAR2(250) := 'CS_FORUM_MESSAGES_TL_N4';
1047 l_mode VARCHAR2(10) := bmode;
1048 l_return_status VARCHAR2(1) := fnd_api.G_RET_STS_ERROR;
1049 BEGIN
1050 -- Initialize some variables
1051 retcode := 2; -- init return val to FAIL
1052
1053 IF l_mode IS NULL THEN
1054 l_mode := 'S';
1055 END IF;
1056
1057 IF is_validate_mode(l_mode) = 'N' THEN
1058 RAISE invalid_mode_error;
1059 END IF;
1060
1061 -- check whether it is 'DR'
1062 IF l_mode = 'DR' THEN
1063 -- At this point we can assume that we can safely drop the index.
1064 Drop_Index(index3,
1065 errbuf,
1066 l_return_status);
1067 IF l_return_status <> fnd_api.G_RET_STS_SUCCESS THEN
1068 RAISE drop_index_error;
1069 END IF;
1070
1071 Create_Forum_Index(pworker,
1072 errbuf,
1073 l_return_status);
1074 IF l_return_status <> fnd_api.G_RET_STS_SUCCESS THEN
1075 RAISE create_index_error;
1076 END IF;
1077 ELSE
1078 -- 4321268
1079 IF (pworker IS NULL OR pworker = 0) AND l_mode = 'R' THEN
1080 populate_forum_index (
1081 x_msg_error => errbuf,
1082 x_return_status => l_return_status
1083 );
1084 Else
1085 Sync_index( index3, l_mode, PWORKER );
1086 END IF;
1087 -- 4321268_eof
1088 END IF;
1089
1090 -- Return successfully
1091 errbuf := fnd_message.get_string('CS', 'CS_KB_C_SUCCESS');
1092 retcode := 0;
1093 EXCEPTION
1094 WHEN invalid_mode_error THEN
1095 BEGIN
1096 errbuf := fnd_message.get_string('CS', 'CS_KB_SYN_INDEX_INV_MODE');
1097 END;
1098 WHEN drop_index_error THEN
1099 BEGIN
1100 FND_FILE.PUT_LINE(FND_FILE.LOG, errbuf);
1101 EXCEPTION
1102 WHEN others THEN
1103 NULL;
1104 END;
1105 WHEN create_index_error THEN
1106 BEGIN
1107 FND_FILE.PUT_LINE(FND_FILE.LOG, errbuf);
1108 EXCEPTION
1109 WHEN others THEN
1110 NULL;
1111 END;
1112 WHEN others THEN
1113 errbuf := 'Sync_Forum_Index: '||
1114 fnd_message.GET_STRING('CS','CS_KB_C_UNEXP_ERR')||' '||
1115 SQLERRM;
1116 BEGIN
1117 FND_FILE.PUT_LINE(FND_FILE.LOG, errbuf);
1118 EXCEPTION
1119 WHEN others THEN
1120 NULL;
1121 END;
1122 END Sync_Forum_Index;
1123
1124 PROCEDURE Sync_Soln_Cat_Index(ERRBUF OUT NOCOPY VARCHAR2,
1125 RETCODE OUT NOCOPY NUMBER,
1126 BMODE IN VARCHAR2,
1127 pworker IN NUMBER DEFAULT 0)
1128 IS
1129 index1 VARCHAR2(250) := 'CS_KB_SOLN_CAT_TL_N1';
1130 l_mode VARCHAR2(10) := bmode;
1131 l_return_status VARCHAR2(1) := fnd_api.G_RET_STS_ERROR;
1132
1133 BEGIN
1134 retcode := 2;
1135
1136 IF l_mode IS NULL THEN
1137 l_mode := 'S';
1138 END IF;
1139
1140 IF is_validate_mode(l_mode) = 'N' THEN
1141 RAISE invalid_mode_error;
1142 END IF;
1143
1144 -- check whether it is 'DR'
1145 IF l_mode = 'DR' THEN
1146 -- At this point we can assume that we can safely drop the index.
1147 Drop_Index(index1,
1148 errbuf,
1149 l_return_status);
1150 IF l_return_status <> fnd_api.G_RET_STS_SUCCESS THEN
1151 RAISE drop_index_error;
1152 END IF;
1153
1154 Create_Soln_Cat_Index(pworker,
1155 errbuf,
1156 l_return_status);
1157 IF l_return_status <> fnd_api.G_RET_STS_SUCCESS THEN
1158 RAISE create_index_error;
1159 END IF;
1160 ELSE
1161 -- 4321268
1162 IF (pworker IS NULL OR pworker = 0) AND l_mode = 'R' THEN
1163 populate_soln_cat_index (
1164 x_msg_error => errbuf,
1165 x_return_status => l_return_status
1166 );
1167 Else
1168 Sync_index( index1, l_mode, PWORKER );
1169 END IF;
1170 -- 4321268_eof
1171 END IF;
1172
1173 -- Return successfully
1174 errbuf := fnd_message.get_string('CS', 'CS_KB_C_SUCCESS');
1175 retcode := 0;
1176 EXCEPTION
1177 WHEN invalid_mode_error THEN
1178 BEGIN
1179 errbuf := fnd_message.get_string('CS', 'CS_KB_SYN_INDEX_INV_MODE');
1180 END;
1181 WHEN drop_index_error THEN
1182 BEGIN
1183 FND_FILE.PUT_LINE(FND_FILE.LOG, errbuf);
1184 EXCEPTION
1185 WHEN others THEN
1186 NULL;
1187 END;
1188 WHEN create_index_error THEN
1189 BEGIN
1190 FND_FILE.PUT_LINE(FND_FILE.LOG, errbuf);
1191 EXCEPTION
1192 WHEN others THEN
1193 NULL;
1194 END;
1195 WHEN others THEN
1196 errbuf := 'Sync_Soln_Cat_Index: '||
1197 fnd_message.GET_STRING('CS','CS_KB_C_UNEXP_ERR')||' '||
1198 SQLERRM;
1199 BEGIN
1200 FND_FILE.PUT_LINE(FND_FILE.LOG, errbuf);
1201 EXCEPTION
1202 WHEN others THEN
1203 NULL;
1204 END;
1205 END Sync_Soln_Cat_Index;
1206
1207 PROCEDURE del_sync_prog
1208 IS
1209 BEGIN
1210 fnd_program.delete_program ('CS_KB_SYNC_INDEX', 'CS');
1211 fnd_program.delete_executable ('CS_KB_SYNC_INDEX', 'CS');
1212 COMMIT;
1213 END del_sync_prog;
1214
1215
1216 PROCEDURE update_set_count_sum (ERRBUF OUT NOCOPY VARCHAR2,
1217 RETCODE OUT NOCOPY NUMBER)
1218 AS
1219
1220 TYPE list_of_def_id_type IS TABLE OF CS_KB_USED_SUM_DEFS_B.DEF_ID%TYPE
1221 INDEX BY BINARY_INTEGER;
1222 list_of_def_id list_of_def_id_type;
1223 TYPE list_of_days_type IS TABLE OF CS_KB_USED_SUM_DEFS_B.DAYS%TYPE
1224 INDEX BY BINARY_INTEGER;
1225 list_of_days list_of_days_type;
1226 i NUMBER(10);
1227 v_used_count CS_KB_SET_USED_SUMS.USED_COUNT%TYPE;
1228 current_date DATE;
1229 whether_exist NUMBER:=0;
1230 x_user_id NUMBER;
1231 x_login_id NUMBER;
1232
1233 CURSOR set_cursor IS
1234 SELECT SET_ID FROM CS_KB_SETS_B;
1235 BEGIN
1236 SELECT SysDate INTO current_date FROM dual;
1237 x_user_id := FND_GLOBAL.user_id;
1238 x_login_id := FND_GLOBAL.login_id;
1239
1240 SELECT def_id, days BULK COLLECT INTO list_of_def_id, list_of_days
1241 FROM CS_KB_USED_SUM_DEFS_B;
1242
1243 -- for each set
1244 FOR set_record IN set_cursor LOOP
1245
1246 -- for each used summary
1247 i:= list_of_def_id.FIRST;
1248 WHILE (i IS NOT NULL) LOOP
1249
1250 -- count
1251 SELECT count(H.HISTORY_ID) INTO v_used_count
1252 FROM CS_KB_HISTORIES_B H, CS_KB_SET_USED_HISTS USED_HISTS
1253 WHERE H.HISTORY_ID=USED_HISTS.HISTORY_ID AND
1254 USED_HISTS.SET_ID=set_record.set_id AND
1255 USED_HISTS.USED_TYPE=CS_KNOWLEDGE_PVT.G_PF AND
1256 ((current_date-H.entry_date)<=list_of_days(i));
1257
1258 IF(v_used_count> 0) THEN
1259
1260 -- insert or update to set_used_sum
1261 SELECT count(SET_ID) INTO whether_exist
1262 FROM CS_KB_SET_USED_SUMS
1263 WHERE SET_ID=set_record.SET_ID AND DEF_ID=list_of_def_id(i);
1264
1265 IF (whether_exist=0) THEN
1266
1267 INSERT INTO CS_KB_SET_USED_SUMS (
1268 SET_ID,
1269 DEF_ID,
1270 USED_COUNT,
1271 CREATION_DATE,
1272 CREATED_BY,
1273 LAST_UPDATE_DATE,
1274 LAST_UPDATED_BY,
1275 LAST_UPDATE_LOGIN)
1276 VALUES (
1277 set_record.set_id,
1278 list_of_def_id(i),
1279 v_used_count,
1280 current_date,
1281 x_user_id, --to_number(FND_PROFILE.VALUE ('USER_ID')),
1282 current_date,
1283 x_user_id, --to_number(FND_PROFILE.VALUE ('USER_ID')),
1284 x_login_id --to_number(FND_PROFILE.VALUE('LOGIN_ID'))
1285 );
1286
1287 ELSE
1288
1289 UPDATE CS_KB_SET_USED_SUMS SET
1290 USED_COUNT=v_used_count,
1291 LAST_UPDATE_DATE=current_date,
1292 LAST_UPDATED_BY=x_user_id, --to_number(FND_PROFILE.VALUE ('USER_ID')),
1293 LAST_UPDATE_LOGIN=x_login_id --to_number(FND_PROFILE.VALUE('LOGIN_ID'))
1294 WHERE set_id = set_record.set_id
1295 AND def_id = list_of_def_id(i);
1296 END IF;
1297
1298 ELSIF v_used_count = 0 THEN
1299
1300 DELETE FROM CS_KB_SET_USED_SUMS
1301 WHERE set_id = set_record.set_id
1302 AND def_id = list_of_def_id(i);
1303
1304 END IF;
1305
1306 i:=list_of_def_id.NEXT(i);
1307 END LOOP;
1308 END LOOP;
1309
1310 --clean up deleted summary definition entries
1311 DELETE FROM cs_kb_set_used_sums
1312 WHERE def_id NOT IN (SELECT def_id
1313 FROM cs_kb_used_sum_defs_b);
1314
1315 COMMIT;
1316 retcode := 0;
1317 END update_set_count_sum;
1318
1319
1320 -- klou (SRCHEFF), since 11.5.10
1321 /**
1322 * UPDATE THE magic word PROFILE.
1323 *
1324 */
1325 PROCEDURE Update_Magic_Word IS
1326 CURSOR Get_Magic_Word_Csr IS
1327 SELECT fnd_profile.value('CS_KB_SEARCH_NONEXIST_KEYWORD') FROM dual;
1328
1329 CURSOR Test_Magic_Word_Csr(p_keyword VARCHAR2) IS
1330 SELECT NULL
1331 FROM cs_kb_sets_vl SetEO
1332 WHERE
1333 contains(SetEO.composite_assoc_index, p_keyword, 10) >= 1
1334 AND ROWNUM < 2
1335 AND SetEO.status = 'PUB';
1336
1337 CURSOR Get_Random_Word_Csr IS
1338 /*
1339 dbms_random.string(opt => 'l', len => 8)
1340 different opt VALUES are:
1341 'u' -- upper case
1342 'l' -- lower case
1343 'a' -- alpha characters only (mixed case)
1344 'x' -- any alpha-numeric characters (upper)
1345 'p' -- any printable characters
1346 */
1347 SELECT dbms_random.string( 'l', 5) FROM dual;
1348
1349 l_magic_word VARCHAR2(240) := NULL;
1350 l_old_magic_word VARCHAR2(240) := NULL;
1351 l_result Test_Magic_Word_Csr%ROWTYPE;
1352
1353 BEGIN
1354 SAVEPOINT Update_Magic_Word_Sav;
1355 -- get magic word
1356 OPEN Get_Magic_Word_Csr;
1357 FETCH Get_Magic_Word_Csr INTO l_magic_word;
1358 CLOSE Get_Magic_Word_Csr;
1359
1360 IF l_magic_word IS NULL THEN
1361 OPEN Get_Random_Word_Csr;
1362 FETCH Get_Random_Word_Csr INTO l_magic_word;
1363 CLOSE Get_Random_Word_Csr;
1364 -- l_magic_word := 'xyxyz';
1365 END IF;
1366
1367 -- Backup l_magic_word
1368 l_old_magic_word := l_magic_word;
1369 --dbms_output.put_line('magic word is '||l_magic_word);
1370 LOOP
1371 OPEN Test_Magic_Word_Csr(l_magic_word);
1372 FETCH Test_Magic_Word_Csr INTO l_result;
1373 EXIT WHEN Test_Magic_Word_Csr%NOTFOUND;
1374 CLOSE Test_Magic_Word_Csr;
1375
1376 OPEN Get_Random_Word_Csr;
1377 FETCH Get_Random_Word_Csr INTO l_magic_word;
1378 CLOSE Get_Random_Word_Csr;
1379
1380 END LOOP;
1381
1382 IF Test_Magic_Word_Csr%ISOPEN THEN
1383 CLOSE Test_Magic_Word_Csr;
1384 END IF;
1385
1386 IF l_magic_word <> l_old_magic_word THEN
1387 -- Update profile
1388 IF Fnd_Profile.Save(
1389 X_NAME => 'CS_KB_SEARCH_NONEXIST_KEYWORD', /* Profile name you are setting */
1390 X_VALUE => l_magic_word, /* Profile value you are setting */
1391 X_LEVEL_NAME => 'SITE' /* 'SITE', 'APPL', 'RESP', or 'USER' */
1392 ) THEN
1393 COMMIT WORK;
1394 END IF;
1395 END IF;
1396
1397 EXCEPTION
1398 WHEN Others THEN
1399 ROLLBACK TO Update_Magic_Word_Sav;
1400 END Update_Magic_Word;
1401
1402
1403 PROCEDURE Update_Usage_Score(ERRBUF OUT NOCOPY VARCHAR2,
1404 RETCODE OUT NOCOPY NUMBER) AS
1405
1406 BEGIN
1407 SAVEPOINT Update_Usage_Score_Sav;
1408 Cs_Knowledge_Audit_Pvt.Update_Solution_Usage_Score(p_commit =>fnd_api.g_true);
1409 errbuf := fnd_message.get_string('CS', 'CS_KB_C_SUCCESS');
1410 retcode := 0;
1411 EXCEPTION
1412 WHEN OTHERS THEN
1413 ROLLBACK TO Update_Usage_Score_Sav;
1414 retcode := 2;
1415 errbuf := sqlerrm;
1416 BEGIN
1417 FND_FILE.PUT_LINE(FND_FILE.LOG, errbuf);
1418 EXCEPTION
1419 WHEN others THEN
1420 NULL;
1421 END;
1422
1423 END Update_Usage_Score;
1424
1425
1426 /*
1427 * Rebuild_Soln_Content_Cache
1428 * Repopulate THE solution content CACHE COLUMN FOR ALL published
1429 * solutions. Content CACHE entries will be commited IN batches.
1430 */
1431 PROCEDURE Rebuild_Soln_Content_Cache
1432 ( errbuf OUT nocopy VARCHAR2,
1433 retcode OUT nocopy NUMBER )
1434 IS
1435 CURSOR all_published_solutions IS
1436 SELECT tl.set_id
1437 FROM cs_kb_sets_tl tl, cs_kb_sets_b b
1438 WHERE b.set_id = tl.set_id
1439 AND b.status = 'PUB';
1440 TYPE solnIdListType IS TABLE OF cs_kb_sets_tl.set_id%TYPE INDEX BY BINARY_INTEGER;
1441 solnIdList solnIdListType;
1442 lCommitBatchSize NUMBER := 100;
1443 lCounter NUMBER := 0;
1444 BEGIN
1445 SAVEPOINT start_rebuild_cache;
1446
1447 -- Fetch out the list of IDs for all published solutions
1448 OPEN all_published_solutions;
1449 FETCH all_published_solutions BULK COLLECT INTO solnIdList;
1450 CLOSE all_published_solutions;
1451
1452 -- Loop through the solution id list and repopulate the content
1453 -- cache for each solution. Commit will be performed for every
1454 -- lCommitBatchSize repopulations performed.
1455 FOR i IN solnIdList.FIRST..solnIdList.LAST LOOP
1456 cs_kb_sync_index_pkg.populate_soln_content_cache(solnIdList(i));
1457 lCounter := lCounter + 1;
1458 IF ( lCounter = lCommitBatchSize ) THEN
1459 COMMIT;
1460 lCounter := 0;
1461 END IF;
1462 END LOOP;
1463 COMMIT;
1464 errbuf := fnd_message.get_string('CS', 'CS_KB_C_SUCCESS');
1465 retcode := 0;
1466 EXCEPTION
1467 WHEN others THEN
1468 ROLLBACK TO start_rebuild_cache;
1469 errbuf := 'Rebuild_Soln_Content_Cache: '||fnd_message.GET_STRING('CS','CS_KB_C_UNEXP_ERR')||' '||SQLERRM;
1470 -- Write out error to concurrent program log
1471 BEGIN
1472 FND_FILE.PUT_LINE(FND_FILE.LOG, errbuf);
1473 EXCEPTION
1474 WHEN others THEN
1475 NULL;
1476 END;
1477 END;
1478
1479 /*
1480 * Mark_Idx_on_Sec_Change
1481 * Mark text INDEX COLUMNS (solutions AND statements) WHEN KM
1482 * security setup changes. Marking THE text COLUMNS IS done OFF-line
1483 * IN a concurrent program TO give better UI response TIME.
1484 * THE way THE program works IS BY passing IN a security CHANGE
1485 * action TYPE code. FOR EACH action TYPE, there IS a LIST OF
1486 * PARAMETERS that get passed THROUGH parameter1-4.
1487 */
1488 PROCEDURE Mark_Idx_on_Sec_Change
1489 ( ERRBUF OUT NOCOPY VARCHAR2,
1490 RETCODE OUT NOCOPY NUMBER,
1491 SECURITY_CHANGE_ACTION_TYPE IN VARCHAR2 DEFAULT NULL,
1492 PARAMETER1 IN NUMBER DEFAULT NULL,
1493 PARAMETER2 IN NUMBER DEFAULT NULL )
1494 IS
1495 l_orig_visibility_id NUMBER := 0;
1496 l_orig_parent_category_id NUMBER := 0;
1497 l_visibility_id NUMBER := 0;
1498 l_category_id NUMBER := 0;
1499 l_cat_grp_id NUMBER := 0;
1500 BEGIN
1501 -- Initialize some variables
1502 retcode := ERROR; -- init return val to FAIL
1503
1504 FND_FILE.PUT_LINE(FND_FILE.LOG, fnd_message.get_string('CS', 'CS_KB_SYNC_IND_BEG')||' '|| 'Mark_Idx_on_Sec_Change');
1505
1506 -- Call out to appropriate helper function for the
1507 -- security setup change action type
1508 IF ( security_change_action_type = 'ADD_VIS' )
1509 THEN
1510 FND_FILE.PUT_LINE(FND_FILE.LOG, fnd_message.get_string('CS', 'CS_KB_SYNC_IND_PROC')||' '|| 'ADD_VIS');
1511 l_visibility_id := PARAMETER1;
1512 cs_kb_sync_index_pkg.Mark_Idx_on_Add_Vis( l_visibility_id );
1513 ELSIF ( security_change_action_type = 'REM_VIS' )
1514 THEN
1515 FND_FILE.PUT_LINE(FND_FILE.LOG, fnd_message.get_string('CS', 'CS_KB_SYNC_IND_PROC')||' '|| 'REM_VIS');
1516 l_visibility_id := PARAMETER1;
1517 cs_kb_sync_index_pkg.Mark_Idx_on_Rem_Vis( l_visibility_id );
1518 ELSIF ( security_change_action_type = 'CHANGE_CAT_VIS' )
1519 THEN
1520 FND_FILE.PUT_LINE(FND_FILE.LOG, fnd_message.get_string('CS', 'CS_KB_SYNC_IND_PROC')||' '|| 'CHANGE_CAT_VIS');
1521 l_category_id := PARAMETER1;
1522 l_orig_visibility_id := PARAMETER2;
1523 cs_kb_sync_index_pkg.Mark_Idx_on_Change_Cat_Vis( l_category_id, l_orig_visibility_id );
1524 ELSIF ( security_change_action_type = 'ADD_CAT_TO_CAT_GRP' )
1525 THEN
1526 FND_FILE.PUT_LINE(FND_FILE.LOG, fnd_message.get_string('CS', 'CS_KB_SYNC_IND_PROC')||' '|| 'ADD_CAT_TO_CAT_GRP');
1527 l_cat_grp_id := PARAMETER1;
1528 l_category_id := PARAMETER2;
1529 cs_kb_sync_index_pkg.Mark_Idx_on_Add_Cat_To_Cat_Grp( l_cat_grp_id, l_category_id );
1530 ELSIF ( security_change_action_type = 'REM_CAT_FROM_CAT_GRP' )
1531 THEN
1532 FND_FILE.PUT_LINE(FND_FILE.LOG, fnd_message.get_string('CS', 'CS_KB_SYNC_IND_PROC')||' '|| 'REM_CAT_FROM_CAT_GRP');
1533 l_cat_grp_id := PARAMETER1;
1534 l_category_id := PARAMETER2;
1535 cs_kb_sync_index_pkg.Mark_Idx_on_Rem_Cat_fr_Cat_Grp( l_cat_grp_id, l_category_id );
1536 ELSIF ( security_change_action_type = 'CHANGE_PARENT_CAT' )
1537 THEN
1538 FND_FILE.PUT_LINE(FND_FILE.LOG, fnd_message.get_string('CS', 'CS_KB_SYNC_IND_PROC')||' '|| 'CHANGE_PARENT_CAT');
1539 l_category_id := PARAMETER1;
1540 l_orig_parent_category_id := PARAMETER2;
1541 cs_kb_sync_index_pkg.Mark_Idx_on_Change_Parent_Cat( l_category_id, l_orig_parent_category_id );
1542 ELSE -- invalid action
1543
1544 FND_FILE.PUT_LINE(FND_FILE.LOG, fnd_message.get_string('CS', 'CS_KB_SYNC_IND_INV_TYPE'));
1545 -- 'Error: Invalid change security setup action type specified'
1546 RAISE invalid_action_error;
1547 END IF;
1548 COMMIT;
1549 -- Set return value and log message to Success
1550 FND_FILE.PUT_LINE(FND_FILE.LOG, fnd_message.get_string('CS', 'CS_KB_SYNC_SUCESS_END'));
1551 -- 'Successfully Completed.'
1552 errbuf := fnd_message.get_string('CS', 'CS_KB_C_SUCCESS');
1553 retcode := SUCCESS;
1554
1555 EXCEPTION
1556 WHEN invalid_action_error THEN
1557 BEGIN
1558 errbuf := fnd_message.get_string('CS', 'CS_KB_SYN_INDEX_INV_ACT');
1559 -- 'Invalid action specified'
1560 END;
1561 WHEN others THEN
1562 ROLLBACK;
1563 errbuf := 'Mark_Idx_on_Sec_Change: '||fnd_message.GET_STRING('CS','CS_KB_C_UNEXP_ERR')||' '||SQLERRM;
1564 -- Write out error to concurrent program log
1565 BEGIN
1566 FND_FILE.PUT_LINE(FND_FILE.LOG, errbuf);
1567 EXCEPTION
1568 WHEN others THEN
1569 NULL;
1570 END;
1571 END Mark_Idx_on_Sec_Change;
1572
1573 END CS_KB_CONC_PROG_PKG;