Home » Server Options » Text & interMedia » Executing CTX_DOC.MARKUP in memory from Pro*C
Executing CTX_DOC.MARKUP in memory from Pro*C [message #75985] Tue, 17 September 2002 06:52 Go to next message
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 #75988 is a reply to message #75985] Tue, 24 September 2002 07:40 Go to previous message
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);
}
Previous Topic: Re: rename column
Next Topic: What am I doing wrong? My currency converter is not working(Using visual c++)
Goto Forum:
  


Current Time: Thu Apr 18 00:27:47 CDT 2024