Home » Developer & Programmer » Precompilers, OCI & OCCI » Executing CTX_DOC.MARKUP in memory from Pro*C
Executing CTX_DOC.MARKUP in memory from Pro*C [message #93656] |
Tue, 17 September 2002 07:07 |
Laurent
Messages: 8 Registered: April 2002
|
Junior Member |
|
|
I'd like to markup text using the MARKUP command from a program written in Pro*C.
I can do it via a table, asking CTX_DOC.MARKUP to write its result in a CLOB column, and then read this CLOB column in my Pro*C but it's realy too slow.
Thus, I'm trying to call CTX_DOC.MARKUP so that it store the marked-up text to an in-memory CLOB (much more fater then "result in table" solution when executed under SQLPLUS).
My problem is that I don't know how to declare this CLOB so that I can use it in the C part of my program:
According to Oracle's manual, my program looks like:
EXEC SQL BEGIN DECLARE SECTION;
VARCHAR IndexTableName[[30+1]];
VARCHAR TextKey[[30+1]];
OCIClobLocator *pClobLocator;
EXEC SQL END DECLARE SECTION;
EXEC SQL ALLOCATE :pClobLocator;
IndexTableName.len = sprintf((char*) IndexTableName.arr, "MyTable");
TextKey.len = sprintf((char*) TextKey.arr, "Text to be marked up");
/* Call external CTX_DOC.MARKUP function */
EXEC SQL EXECUTE
DECLARE
MarkedDoc clob;
BEGIN
CTX_DOC.MARKUP(:IndexTableName, :TextKey, :TextQuery,
MarkedDoc, /* (test 1) pClobLocator, */
FALSE,
'TEXT_DEFAULT',
'<HIGHLIGHT NAME="ctx%CURNUM">', /* startag */
'</HIGHLIGHT>', /* endtag */
'<PREV-HIGHLIGHT NAME="ctx%PREVNUM">', /* prevtag */
'<NEXT-HIGHLIGHT NAME="ctx%NEXTNUM">' /* nexttag */
);
/* (test 2) DBMS_LOB.COPY(:pClobLocator, MarkedDoc, DBMS_LOB.GETLENGTH(MarkedDoc), 1, 1); */
/* DBMS_LOB.FREETEMPORARY(MarkedDoc); */
END;
END-EXEC;
...
But here, in C part, "MarkedDoc" is no more known.
(test 1) I've tried to replace "MarkedDoc" by "pClobLocator" in the "EXEC SQL EXECUTE" part but it doesn't work; at execution, CTX_DOC.MARKUP returns "ORA-22275: invalid LOB locator specified"
(test 2) I've also tried to copy "MarkedDoc" into "pClobLocator", but DBMS_LOB.COPY gave me the same "ORA-22275: invalid LOB locator specified"
Any help/comment/suggestion is welcome.
(nb: Oracle database v8.0.6)
|
|
|
Re: Executing CTX_DOC.MARKUP in memory from Pro*C [message #93664 is a reply to message #93656] |
Tue, 24 September 2002 07:48 |
Laurent
Messages: 8 Registered: April 2002
|
Junior Member |
|
|
Here is a solution to my problem: write an sql procedure that call CTX_DOC.MARKUP, and a Pro-C function that calls this procedure using varchar2 parameter to get the Clob content (need a loop to get the whole clob):
Oracle package:
CREATE OR REPLACE PACKAGE SIP_PACKAGE IS
PROCEDURE SIP_Markup(Obj_Ref_Id IN number, Offset IN number, WordToBeMarked IN varchar2, TotalNbCharInClob OUT number, MarkedDoc OUT varchar2, NbCharReadInMarkedDoc OUT number);
END;
/
CREATE OR REPLACE PACKAGE BODY SIP_PACKAGE IS
GlobalClob_for_SIP_Markup clob; /* Used by procedure SIP_Markup */
PROCEDURE SIP_Markup(Obj_Ref_Id IN number, Offset IN number, WordToBeMarked IN varchar2, TotalNbCharInClob OUT number, MarkedDoc OUT varchar2, NbCharReadInMarkedDoc OUT number) IS
KeyValue varchar2(32);
NbBytesToRead number;
res varchar2(32767);
ChunkSize integer;
TmpClob clob;
BEGIN
TotalNbCharInClob := 0;
NbCharReadInMarkedDoc := 0;
MarkedDoc := '';
if (Offset = 0) then
KeyValue := to_char(Obj_Ref_Id);
CTX_DOC.MARKUP('MY_INDEX' , KeyValue, WordToBeMarked, TmpClob, FALSE, 'TEXT_DEFAULT', '<HIGHLIGHT NAME="ctx%CURNUM">', '</HIGHLIGHT>', '<PREV-HIGHLIGHT NAME="ctx%PREVNUM">', '<NEXT-HIGHLIGHT NAME="ctx%NEXTNUM">');
GlobalClob_for_SIP_Markup := TmpClob;
DBMS_LOB.FREETEMPORARY(TmpClob);
end if;
TotalNbCharInClob := DBMS_LOB.GETLENGTH(GlobalClob_for_SIP_Markup );
Trace_Msg('TotalNbCharInClob =' || to_char(TotalNbCharInClob));
/* Set NbCharReadInMarkedDoc to number of char to be read (!!! because UTF8 */
/* characters are coded on several bytes, this number is not the same as */
/* the number of bytes to be read !!!) */
/* Note: read multiple of LOB's chunksize to increase performances */
ChunkSize := DBMS_LOB.GETCHUNKSIZE(GlobalClob_for_SIP_Markup );
NbCharReadInMarkedDoc := 32767/2;
NbCharReadInMarkedDoc := (NbCharReadInMarkedDoc /ChunkSize) * ChunkSize;
DBMS_LOB.READ(GlobalClob_for_SIP_Markup , NbCharReadInMarkedDoc, Offset+1, MarkedDoc );
Trace_Msg('NbCharReadInMarkedDoc =' || to_char(NbCharReadInMarkedDoc));
END;
END; /* CREATE OR REPLACE PACKAGE BODY SIP_PACKAGE */
/
Pro*C function:
ErrorType API_CtxMarkup(Obj_Ref_Id, TextQuery, ppMarkedDoc, pMarkedDocLen)
/* IN */
int Obj_Ref_Id; /* Key of document to be marked */
char TextQuery[[]]; /* Word to be marked */
/* OUT */
char **ppMarkedDoc; /* Returned marked document */
int *pMarkedDocLen; /* Nb bytes returned in ppMarkedDoc */
{
int Erc = 0;
int NbBytesAllocated = 0;
EXEC SQL BEGIN DECLARE SECTION;
int Offset_LastReadChar;
int NbCharReadInMarkedDoc;
VARCHAR MarkedDoc[[32000]];
int ClobTotalNbChars;
EXEC SQL END DECLARE SECTION;
/* Check the function's parameters */
if (ppMarkedDoc == NULL)
{
printf("(%d) given ppMarkedDoc is NULLn", __LINE__);
Erc = 1;
}
if (pMarkedDocLen == NULL)
{
printf("(%d) given pMarkedDocLen is NULLn", __LINE__);
Erc = 1;
}
/* Initialization: set returned parameters */
if (Erc == 0)
{
*ppMarkedDoc = NULL;
*pMarkedDocLen = 0;
}
/* Call the Oracle CTX_DOC.MARKUP function */
if (Erc == 0)
{
EXEC SQL WHENEVER SQLERROR CONTINUE;
EXEC SQL WHENEVER NOT FOUND CONTINUE;
MarkedDoc.len = sprintf((char *) MarkedDoc.arr, "");
Offset_LastReadChar = 0;
ClobTotalNbChars = 1; /* Just for loop to begin */
while ((Erc == 0) && (Offset_LastReadChar < ClobTotalNbChars))
{
EXEC SQL EXECUTE
BEGIN
SIP_PACKAGE.SIP_Markup(:Obj_Ref_Id, :Offset_LastReadChar, :TextQuery, :ClobTotalNbChars, :MarkedDoc, :NbCharReadInMarkedDoc);
END;
END-EXEC;
Erc = sqlca.sqlcode;
MarkedDoc.arr[[MarkedDoc.len]] = ' ';
if (Erc == 0)
{ /* Add this part of the blob to *ppMarkedDoc */
if (*ppMarkedDoc == NULL)
{
NbBytesAllocated = ClobTotalNbChars + 1000; /* Keep more place because of header ("<SIP-SECTION>...</SIP-SECTION>") added by InterMedia Text, and because UTF8 characters may need more than 1 byte */
*ppMarkedDoc = malloc(NbBytesAllocated+1);
}
else if (NbBytesAllocated < (*pMarkedDocLen+strlen((char*) MarkedDoc.arr)) )
{ /* Not enough memory allocated in *ppMarkedDoc. */
/* May happen because ClobTotalNbChars is a number of chars (not number of bytes) and UTF8 character may need several bytes */
NbBytesAllocated = (*pMarkedDocLen+strlen((char*) MarkedDoc.arr));
*ppMarkedDoc = realloc(*ppMarkedDoc, NbBytesAllocated+1);
}
*pMarkedDocLen += sprintf((*ppMarkedDoc + *pMarkedDocLen), "%s", (char*) MarkedDoc.arr);
Offset_LastReadChar += NbCharReadInMarkedDoc;
}
} /* while */
}
return(Erc);
}
|
|
|
Goto Forum:
Current Time: Sun Nov 24 14:38:36 CST 2024
|