Thursday 18 April 2013

CTX_REPORT Package Code

CREATE OR REPLACE package ctx_report authid current_user as

-- constants
FMT_TEXT  constant varchar2(10) := 'TEXT';
FMT_XML   constant varchar2(10) := 'XML';

-- type declaration
type query_record is record(times number, query varchar2(4000));
type query_table is table of query_record index by binary_integer;


/*--------------------------- query_log_summary -----------------------------*/
/*
  NAME
    query_log_summary - get the most(least) frequent queries from the query log file

  DESCRIPTION
    This version of query_summary returns the results into a PL/SQL table

  ARGUMENTS
    logfile      (IN)     the name of query log file
    indexname    (IN)     the name of the context index, the default is null which
                          will return result for all context indexes
    result_table (IN OUT) query_table to which to write the result
    row_num      (IN)     the number of queries you want
    most_freq    (IN)     whether you want the most frequent or least frequent quries

*/
procedure query_log_summary(
  logfile       in varchar2,
  indexname     in varchar2 default null,
  result_table  in out nocopy query_table,
  row_num       in number default 50,
  most_freq     in boolean default true,
  has_hit       in boolean default true
);


/*--------------------------- describe_index --------------------------------*/
/*
  NAME
    describe_index

  DESCRIPTION
    create a report describing the index.  This includes the settings of
    the index meta-data, the indexing objects used, the settings of the
    attributes of the objects, and index partition descriptions, if any

  ARGUMENTS
    index_name    (IN)     the name of the index to describe
    report        (IN OUT) CLOB locator to which to write the report
    report_format (IN)     report format
  NOTES
    if report is NULL, a session-duration temporary CLOB will be created
    and returned.  It is the caller's responsibility to free this temporary
    CLOB as needed.

    report clob will be truncated before report is generated, so any
    existing contents will be overwritten by this call
*/
procedure describe_index(
  index_name     in varchar2,
  report         in out nocopy clob,
  report_format  in varchar2 DEFAULT FMT_TEXT
);

function describe_index(
  index_name     in varchar2,
  report_format  in varchar2 DEFAULT FMT_TEXT
) return clob;

/*--------------------------- describe_policy -------------------------------*/
/*
  NAME
    describe_policy

  DESCRIPTION
    create a report describing the policy.  This includes the settings of
    the policy meta-data, the indexing objects used, the settings of the
    attributes of the objects.

  ARGUMENTS
    policy_name (IN)     the name of the policy to describe
    report     (IN OUT) CLOB locator to which to write the report
    report_format (IN)     report format
  NOTES
    if report is NULL, a session-duration temporary CLOB will be created
    and returned.  It is the caller's responsibility to free this temporary
    CLOB as needed.

    report clob will be truncated before report is generated, so any
    existing contents will be overwritten by this call
*/
procedure describe_policy(
  policy_name    in varchar2,
  report         in out nocopy clob,
  report_format  in varchar2 DEFAULT FMT_TEXT
);

function describe_policy(
  policy_name    in varchar2,
  report_format  in varchar2 DEFAULT FMT_TEXT
) return clob;

/*-------------------------- create_index_script ----------------------------*/
/*
  NAME
    create_index_script

  DESCRIPTION
    create a SQL*Plus script which will create a text index that duplicates
    the named text index.

  ARGUMENTS
    index_name      (IN)     the name of the index
    report          (IN OUT) CLOB locator to which to write the script
    prefname_prefix (IN)     optional prefix to use for preference names

  NOTES
    the created script will include creation of preferences identical to
    those used in the named text index

    if report is NULL, a session-duration temporary CLOB will be created
    and returned.  It is the caller's responsibility to free this temporary
    CLOB as needed.

    report clob will be truncated before report is generated, so any
    existing contents will be overwritten by this call

    if prefname_prefix is omitted or NULL, index name will be used
    prefname_prefix follows index length restrictions
*/
procedure create_index_script(
  index_name      in varchar2,
  report          in out nocopy clob,
  prefname_prefix in varchar2 default null
);

function create_index_script(
  index_name      in varchar2,
  prefname_prefix in varchar2 default null
) return clob;

/*-------------------------- create_policy_script ---------------------------*/
/*
  NAME
    create_policy_script

  DESCRIPTION
    create a SQL*Plus script which will create a text policy that duplicates
    the named text policy.

  ARGUMENTS
    policy_name      (IN)     the name of the policy
    report          (IN OUT) CLOB locator to which to write the script
    prefname_prefix (IN)     optional prefix to use for preference names

  NOTES
    the created script will include creation of preferences identical to
    those used in the named text policy

    if report is NULL, a session-duration temporary CLOB will be created
    and returned.  It is the caller's responsibility to free this temporary
    CLOB as needed.

    report clob will be truncated before report is generated, so any
    existing contents will be overwritten by this call

    if prefname_prefix is omitted or NULL, policy name will be used
    prefname_prefix follows policy length restrictions
*/
procedure create_policy_script(
  policy_name      in varchar2,
  report          in out nocopy clob,
  prefname_prefix in varchar2 default null
);

function create_policy_script(
  policy_name      in varchar2,
  prefname_prefix in varchar2 default null
) return clob;


/*--------------------------- index_size --------------------------------*/
/*
  NAME
    index_size

  DESCRIPTION
    create a report showing the internal objects of the text index or
    text index partition, and their tablespaces, allocated, and used sizes

  ARGUMENTS
    index_name (IN)     the name of the index to describe
    report     (IN OUT) CLOB locator to which to write the report
    part_name  (IN)     the name of the index partition (optional)
    report_format  (IN) report format
  NOTES
    if part_name is NULL, and the index is a local partitioned text index,
    then all objects of all partitions will be displayed.  If part_name is
    provided, then only the objects of a particular partition will be
    displayed.

    if report is NULL, a session-duration temporary CLOB will be created
    and returned.  It is the caller's responsibility to free this temporary
    CLOB as needed.

    report clob will be truncated before report is generated, so any
    existing contents will be overwritten by this call
*/
procedure index_size(
  index_name in varchar2,
  report     in out nocopy clob,
  part_name  in varchar2 default null,
  report_format  in varchar2 DEFAULT FMT_TEXT
);

function index_size(
  index_name  in varchar2,
  part_name   in varchar2 default null,
  report_format  in varchar2 DEFAULT FMT_TEXT
) return clob;

/*--------------------------- index_stats --------------------------------*/
/*
  NAME
    index_stats

  DESCRIPTION
    create a report showing various calculated statistics about the text
    index

  ARGUMENTS
    index_name (IN)     the name of the index to describe
    report     (IN OUT) CLOB locator to which to write the report
    part_name  (IN)     the name of the index partition
    frag_stats (IN)     calculate fragmentation statistics?
    list_size  (IN)     number of elements in each compiled list
    report_format  (IN) report format
    stat_type (IN)      Specify teh estimated query stats to output
  NOTES
    this procedure will fully scan the text index tables, so it may take
    a long time to run for large indexes

    if the index is a local partitioned index, then part_name MUST be
    provided.  INDEX_STATS will calculate the statistics for that
    index partition.

    if report is NULL, a session-duration temporary CLOB will be created
    and returned.  It is the caller's responsibility to free this temporary
    CLOB as needed.

    report clob will be truncated before report is generated, so any
    existing contents will be overwritten by this call

    if frag_stats is FALSE, the report will not show any statistics
    relating to size of index data.  However, the operation should
    take less time and resources to calculate the token statistics.

    list_size has a maximum value of 1000

    index_stats will create and use a session-duration temporary
    table, which will be created in CTXSYS temp tablespace.
*/
procedure index_stats(
  index_name in varchar2,
  report     in out nocopy clob,
  part_name  in varchar2 default null,
  frag_stats in boolean default TRUE,
  list_size  in number  default 100,
  report_format  in varchar2 DEFAULT FMT_TEXT,
  stat_type  in varchar2 DEFAULT NULL
);

/*--------------------------- token_info --------------------------------*/
/*
  NAME
    token_info

  DESCRIPTION
    create a report showing the information for a token, decoded

  ARGUMENTS
    index_name     (IN)     the name of the index
    report         (IN OUT) CLOB locator to which to write the report
    token          (IN)     the token text
    token_type     (IN)     the token type
    part_name      (IN)     the name of the index partition
    raw_info       (IN)     include a hex dump of the index data
    decoded_info   (IN)     decode and include docid and offset data
    resolve_docids (IN)     resolve docids to rowids?
     report_format (IN)     report format
  NOTES
    this procedure will fully scan the info for a token, so it may take a
    long time to run for really large tokens.

    if the index is a local partitioned index, then part_name MUST be
    provided.  TOKEN_INFO will apply to just that index partition.

    if report is NULL, a session-duration temporary CLOB will be created
    and returned.  It is the caller's responsibility to free this temporary
    CLOB as needed.

    report clob will be truncated before report is generated, so any
    existing contents will be overwritten by this call

    token may be case-sensitive, depending on the passed-in token type.
    THEME, ZONE, ATTR, PATH, and PATH ATTR tokens are case-sensitive.
    Everything else gets passed through the lexer, so if the index's
    lexer is case-sensitive, the token input is case-sensitive.

    if raw_info is TRUE, the report will include a hex dump of the
    raw data in the token_info column

    if decoded_info is FALSE, ctx_report will not attempt to decode the
    token information.  This is useful when you just want a dump of data.

    To facilitate inline invocation, the boolean arguments are varchar2
    in the function variant.  You can pass in 'Y', 'N', 'YES', 'NO', 'T', 'F',
    'TRUE', or 'FALSE'

*/
procedure token_info(
  index_name      in varchar2,
  report          in out nocopy clob,
  token           in varchar2,
  token_type      in number,
  part_name       in varchar2 default null,
  raw_info        in boolean  default FALSE,
  decoded_info    in boolean  default TRUE,
  report_format   in varchar2 DEFAULT FMT_TEXT
);

function token_info(
  index_name      in varchar2,
  token           in varchar2,
  token_type      in number,
  part_name       in varchar2 default null,
  raw_info        in varchar2 default 'N',
  decoded_info    in varchar2 default 'Y',
  report_format   in varchar2 DEFAULT FMT_TEXT
) return clob;

/*--------------------------- token_type --------------------------------*/
/*
  NAME
    token_type

  DESCRIPTION
    this is a helper function which translates an English name into a
    numeric token type.  This is suitable for use with token_info,
    or any other CTX API which takes in a token_type.

  ARGUMENTS
    index_name     (IN)     the name of the index
    type_name      (IN)     an English name for token_type

  NOTES
    the following is legal input.  All input is case-insensitive.

      input               meaning                             type returned
      ------------------- ----------------------------------- -------------
      TEXT                normal text token                               0
      THEME               theme token                                     1
      ZONE SEC            zone section                                    2
      ATTR TEXT           text that occurs in an attribute                4
      ATTR SEC            attribute section                               5
      PREFIX              prefix token                                    6
      PATH SEC            path section                                    7
      PATH ATTR           path attribute section                          8
      STEM                stem form token                                 9
      ATTR TEXT PREFIX    prefix token occuring in attribute            604
      ATTR TEXT STEM      stem token occuring in attribute              904
      FIELD <name> TEXT   text token in field section <name>          16-79
      FIELD <name> PREFIX prefix token in field section <name>      616-916
      FIELD <name> STEM   stem token in field section <name>        916-979
      NDATA <name>        token in ndata setion <name>              200-299
      MDATA <name>        mdata value in mdata section <name>       400-499

    example:

      typenum := ctx_report.token_type('myindex', 'field author text');

    For FIELD types, the index meta-data needs to be read, so if you are
    going to be calling this a lot for such things, you might want to
    consider caching the values in local variables rather than calling
    token_type over and over again.

    The constant types (0 - 9) also have constants in this package defined.
*/
function token_type(
  index_name in varchar2,
  type_name  in varchar2
) return number;

TOKEN_TYPE_TEXT      constant number := 0;
TOKEN_TYPE_THEME     constant number := 1;
TOKEN_TYPE_ZONE_SEC  constant number := 2;
TOKEN_TYPE_ATTR_TEXT constant number := 4;
TOKEN_TYPE_ATTR_SEC  constant number := 5;
TOKEN_TYPE_PREFIX    constant number := 6;
TOKEN_TYPE_PATH_SEC  constant number := 7;
TOKEN_TYPE_PATH_ATTR constant number := 8;
TOKEN_TYPE_STEM      constant number := 9;
TOKEN_TYPE_ATTR_TXT_PFIX constant number := 604;
TOKEN_TYPE_ATTR_TXT_STEM constant number := 904;

end ctx_report;
/


CREATE OR REPLACE PACKAGE BODY ctx_report AS

PROCEDURE INT_TOKEN_INFO(
  INDEX_NAME      IN VARCHAR2,
  REPORT          IN OUT NOCOPY CLOB,
  TOKEN           IN VARCHAR2,
  TOKEN_TYPE      IN NUMBER,
  PART_NAME       IN VARCHAR2 DEFAULT NULL,
  RAW_INFO        IN BOOLEAN  DEFAULT FALSE,
  DECODED_INFO    IN BOOLEAN  DEFAULT TRUE,
  REPORT_FORMAT   IN VARCHAR2 DEFAULT FMT_TEXT
) IS
  IDX DR_DEF.IDX_REC;
  IXP DR_DEF.IXP_REC;
  L_TOKEN VARCHAR2(64);
  L_TT DR_DEF.VC256_TAB;
  L_RI VARCHAR2(1) := '0';
  L_DI VARCHAR2(1) := '1';
  L_NUM_FMT NUMBER;
BEGIN

  IDX := DRIXMD.GETINDEXREC(INDEX_NAME);
  IXP := DRIXMD.GETPARTITIONREC(PART_NAME, IDX);

  IF (IDX.IDX_TYPE != DRIXMD.IDX_TYPE_CONTEXT) THEN
    DRUE.PUSH(DRIG.GU_IDXTYPE_NOT_SUP);
    RAISE DR_DEF.TEXTILE_ERROR;
  END IF;

  IF (TOKEN IS NULL) THEN
    DRUE.PUSH(DRIG.GU_REQUIRED_NULL, 'TOKEN');
    RAISE DR_DEF.TEXTILE_ERROR;
  END IF;

  IF (TOKEN_TYPE IS NULL) THEN
    DRUE.PUSH(DRIG.GU_REQUIRED_NULL, 'TOKEN_TYPE');
    RAISE DR_DEF.TEXTILE_ERROR;
  END IF;



 
  DRIREP.LOAD_TTYPE_NAMES(IDX, L_TT);
  IF (NOT L_TT.EXISTS(TOKEN_TYPE)) THEN
    DRUE.PUSH(DRIG.PF_INV_ATTRIBUTE_VALUE, 'TOKEN_TYPE', TOKEN_TYPE);
    RAISE DR_DEF.TEXTILE_ERROR;
  END IF;

 
 
 
  IF (TOKEN_TYPE IN (1, 2, 5, 7, 8)) THEN
    L_TOKEN := TOKEN;
  ELSIF (TOKEN_TYPE >= 400 AND TOKEN_TYPE <= 499) THEN
    L_TOKEN := LTRIM(RTRIM(TOKEN));
  ELSIF (TOKEN_TYPE >= 200 AND TOKEN_TYPE <= 299) THEN
    L_TOKEN := LTRIM(RTRIM(TOKEN));
  ELSE
    L_TOKEN := DRVDISP.EXECASOWN_RET1(IDX.IDX_OWNER#,IDX.IDX_OWNER,
                                      IDX.IDX_NAME, NULL,
                                      DRILIST.CMD_INDEX_LEX_SW,
                                      TOKEN, DRIG.BW_SEED_FAILED);
    IF (L_TOKEN IS NULL) THEN
      DRUE.PUSH(DRIG.GU_REQUIRED_NULL, 'TOKEN');
      RAISE DR_DEF.TEXTILE_ERROR;
    END IF;
  END IF;

  IF (RAW_INFO) THEN L_RI := '1'; END IF;
  IF (NOT DECODED_INFO) THEN L_DI := '0'; END IF;

  IF (REPORT_FORMAT = 'XML') THEN
    L_NUM_FMT := 1;
  ELSE
    L_NUM_FMT := 0;
  END IF;


  DRVDISP.EXECASOWN_CLOB(IDX.IDX_OWNER#,IDX.IDX_OWNER,
                         IDX.IDX_NAME,IXP.IXP_NAME,
                         DRILIST.CMD_REPORT_TOKINFO, REPORT,
                         L_TOKEN, TOKEN_TYPE, L_RI, L_DI, L_NUM_FMT);

EXCEPTION
  WHEN DR_DEF.TEXTILE_ERROR THEN
    RAISE DR_DEF.TEXTILE_ERROR;
  WHEN OTHERS THEN
    DRUE.TEXT_ON_STACK(SQLERRM, 'ctx_report.int_token_info');
    RAISE DR_DEF.TEXTILE_ERROR;
END INT_TOKEN_INFO;

PROCEDURE COPY_QUERYTAB (
  RESTAB IN OUT NOCOPY QUERY_TABLE
) IS
BEGIN
  RESTAB.DELETE;
  FOR I IN 1..DRVIMR.R_QUERY.COUNT LOOP
    RESTAB(I).QUERY  := DRVIMR.R_QUERY(I).QUERY;
    RESTAB(I).TIMES := DRVIMR.R_QUERY(I).TIMES;
  END LOOP;
  DRVIMR.R_QUERY.DELETE;
EXCEPTION
  WHEN DR_DEF.TEXTILE_ERROR THEN
    RAISE DR_DEF.TEXTILE_ERROR;
  WHEN OTHERS THEN
    DRUE.TEXT_ON_STACK(SQLERRM, 'ctx_doc.copy_querytab');
    RAISE DR_DEF.TEXTILE_ERROR;
END COPY_QUERYTAB;







PROCEDURE QUERY_LOG_SUMMARY(
  LOGFILE       IN VARCHAR2,
  INDEXNAME     IN VARCHAR2 DEFAULT NULL,
  RESULT_TABLE  IN OUT NOCOPY QUERY_TABLE,
  ROW_NUM       IN NUMBER DEFAULT 50,
  MOST_FREQ     IN BOOLEAN DEFAULT TRUE,
  HAS_HIT       IN BOOLEAN DEFAULT TRUE)

IS
  LOGDIR VARCHAR2(2000) := NULL;
  RET1   VARCHAR2(10);
  RET2   VARCHAR2(10);
  ONOFF  NUMBER;
  HASHIT NUMBER;
BEGIN
  IF (LOGFILE IS NULL) THEN
    DRUE.PUSH(DRIG.CO_LOGFILE_NULL);
    RAISE DR_DEF.TEXTILE_ERROR;
  END IF;

  FOR C1 IN (SELECT PAR_VALUE
               FROM DR$PARAMETER
              WHERE PAR_NAME = 'LOG_DIRECTORY')
  LOOP
    LOGDIR := C1.PAR_VALUE;
  END LOOP;

 
  IF MOST_FREQ THEN
    ONOFF := 1;
  ELSE
    ONOFF := 0;
  END IF;

 
  IF HAS_HIT THEN
    HASHIT := 1;
  ELSE
    HASHIT := 0;
  END IF;

  DRIDISP.EXECTRUST(NULL, NULL, NULL, DRILIST.CMD_REPORT_QUERY_LOG_SUMMARY,
                    ONOFF, ROW_NUM, HASHIT, LOGDIR, LOGFILE, INDEXNAME);
  COPY_QUERYTAB(RESULT_TABLE);
  EXCEPTION
  WHEN DR_DEF.TEXTILE_ERROR THEN
    DRUE.RAISE;
  WHEN OTHERS THEN
    DRUE.TEXT_ON_STACK(SQLERRM, 'ctx_report.query_log_summary');
    DRUE.RAISE;
END QUERY_LOG_SUMMARY;



PROCEDURE DESCRIBE_INDEX(
  INDEX_NAME     IN VARCHAR2,
  REPORT         IN OUT NOCOPY CLOB,
  REPORT_FORMAT  IN VARCHAR2 DEFAULT FMT_TEXT
)
IS
  IDX DR_DEF.IDX_REC;
BEGIN
  DRVUTL.SETINVOKER;
  IDX := DRIXMD.GETINDEXREC(INDEX_NAME);
  DRIREPM.DESCRIBE_INDEX(INDEX_NAME, REPORT, REPORT_FORMAT);
  DRVUTL.CLEARINVOKER;
EXCEPTION
  WHEN DR_DEF.TEXTILE_ERROR THEN
    DRUE.RAISE;
  WHEN OTHERS THEN
    DRUE.TEXT_ON_STACK(SQLERRM, 'ctx_report.describe_index');
    DRUE.RAISE;
END DESCRIBE_INDEX;



FUNCTION DESCRIBE_INDEX(
  INDEX_NAME     IN VARCHAR2,
  REPORT_FORMAT  IN VARCHAR2 DEFAULT FMT_TEXT
) RETURN CLOB
IS
  X CLOB;
  IDX DR_DEF.IDX_REC;
BEGIN
  DRVUTL.SETINVOKER;
  IDX := DRIXMD.GETINDEXREC(INDEX_NAME);
  DBMS_LOB.CREATETEMPORARY(X, TRUE, DBMS_LOB.CALL);
  DRIREPM.DESCRIBE_INDEX(INDEX_NAME, X, REPORT_FORMAT);
  DRVUTL.CLEARINVOKER;
  RETURN X; 
EXCEPTION
  WHEN DR_DEF.TEXTILE_ERROR THEN
    DRUE.RAISE;
  WHEN OTHERS THEN
    DRUE.TEXT_ON_STACK(SQLERRM, 'ctx_report.describe_index');
    DRUE.RAISE;
END DESCRIBE_INDEX;



PROCEDURE DESCRIBE_POLICY(
  POLICY_NAME    IN VARCHAR2,
  REPORT         IN OUT NOCOPY CLOB,
  REPORT_FORMAT  IN VARCHAR2 DEFAULT FMT_TEXT
)
IS
  IDX DR_DEF.IDX_REC;
BEGIN
  DRVUTL.SETINVOKER;
  IDX := DRIXMD.GETINDEXREC(POLICY_NAME,
                            F_ISPOLICY=>DRIXMD.POL_INDEX_OR_POLICY);

 
  IF (DRIXMD.CHKINDEXOPTION(IDX.IDX_ID, 'E') = 1) THEN
    DRUE.PUSH(DRIG.EE_DOCSVC_ENT_POLICY);
    RAISE DR_DEF.TEXTILE_ERROR;
  END IF;
  DRIREPM.DESCRIBE_POLICY(POLICY_NAME, REPORT, REPORT_FORMAT);
  DRVUTL.CLEARINVOKER;
EXCEPTION
  WHEN DR_DEF.TEXTILE_ERROR THEN
    DRUE.RAISE;
  WHEN OTHERS THEN
    DRUE.TEXT_ON_STACK(SQLERRM, 'ctx_report.describe_policy');
    DRUE.RAISE;
END DESCRIBE_POLICY;



FUNCTION DESCRIBE_POLICY(
  POLICY_NAME    IN VARCHAR2,
  REPORT_FORMAT  IN VARCHAR2 DEFAULT FMT_TEXT
) RETURN CLOB
IS
  X CLOB;
  IDX DR_DEF.IDX_REC;
BEGIN
  DRVUTL.SETINVOKER;
  IDX := DRIXMD.GETINDEXREC(POLICY_NAME,
                            F_ISPOLICY=>DRIXMD.POL_INDEX_OR_POLICY);

 
  IF (DRIXMD.CHKINDEXOPTION(IDX.IDX_ID, 'E') = 1) THEN
    DRUE.PUSH(DRIG.EE_DOCSVC_ENT_POLICY);
    RAISE DR_DEF.TEXTILE_ERROR;
  END IF;
  DBMS_LOB.CREATETEMPORARY(X, TRUE, DBMS_LOB.CALL);
  DRIREPM.DESCRIBE_POLICY(POLICY_NAME, X, REPORT_FORMAT);
  DRVUTL.CLEARINVOKER;
  RETURN X; 
EXCEPTION
  WHEN DR_DEF.TEXTILE_ERROR THEN
    DRUE.RAISE;
  WHEN OTHERS THEN
    DRUE.TEXT_ON_STACK(SQLERRM, 'ctx_report.describe_policy');
    DRUE.RAISE;
END DESCRIBE_POLICY;



PROCEDURE CREATE_INDEX_SCRIPT(
  INDEX_NAME      IN VARCHAR2,
  REPORT          IN OUT NOCOPY CLOB,
  PREFNAME_PREFIX IN VARCHAR2 DEFAULT NULL
)
IS
  IDX DR_DEF.IDX_REC;
BEGIN
  DRVUTL.SETINVOKER;
  IDX := DRIXMD.GETINDEXREC(INDEX_NAME);
  DRIREPM.CREATE_INDEX_SCRIPT(INDEX_NAME, REPORT, PREFNAME_PREFIX);
  DRVUTL.CLEARINVOKER;
EXCEPTION
  WHEN DR_DEF.TEXTILE_ERROR THEN
    DRUE.RAISE;
  WHEN OTHERS THEN
    DRUE.TEXT_ON_STACK(SQLERRM, 'ctx_report.create_index_script');
    DRUE.RAISE;
END CREATE_INDEX_SCRIPT;



FUNCTION CREATE_INDEX_SCRIPT(
  INDEX_NAME      IN VARCHAR2,
  PREFNAME_PREFIX IN VARCHAR2 DEFAULT NULL
) RETURN CLOB
IS
  X CLOB;
  IDX DR_DEF.IDX_REC;
BEGIN
  DRVUTL.SETINVOKER;
  IDX := DRIXMD.GETINDEXREC(INDEX_NAME);
  DBMS_LOB.CREATETEMPORARY(X, TRUE, DBMS_LOB.CALL);
  DRIREPM.CREATE_INDEX_SCRIPT(INDEX_NAME, X, PREFNAME_PREFIX);
  DRVUTL.CLEARINVOKER;
  RETURN X; 
EXCEPTION
  WHEN DR_DEF.TEXTILE_ERROR THEN
    DRUE.RAISE;
  WHEN OTHERS THEN
    DRUE.TEXT_ON_STACK(SQLERRM, 'ctx_report.create_index_ssript');
    DRUE.RAISE;
END CREATE_INDEX_SCRIPT;



PROCEDURE CREATE_POLICY_SCRIPT(
  POLICY_NAME      IN VARCHAR2,
  REPORT          IN OUT NOCOPY CLOB,
  PREFNAME_PREFIX IN VARCHAR2 DEFAULT NULL
)
IS
  IDX DR_DEF.IDX_REC;
BEGIN
  DRVUTL.SETINVOKER;
  IDX := DRIXMD.GETINDEXREC(POLICY_NAME,
                            F_ISPOLICY=>DRIXMD.POL_INDEX_OR_POLICY);

 
  IF (DRIXMD.CHKINDEXOPTION(IDX.IDX_ID, 'E') = 1) THEN
    DRUE.PUSH(DRIG.EE_DOCSVC_ENT_POLICY);
    RAISE DR_DEF.TEXTILE_ERROR;
  END IF;
  DRIREPM.CREATE_POLICY_SCRIPT(POLICY_NAME, REPORT, PREFNAME_PREFIX);
  DRVUTL.CLEARINVOKER;
EXCEPTION
  WHEN DR_DEF.TEXTILE_ERROR THEN
    DRUE.RAISE;
  WHEN OTHERS THEN
    DRUE.TEXT_ON_STACK(SQLERRM, 'ctx_report.create_policy_script');
    DRUE.RAISE;
END CREATE_POLICY_SCRIPT;



FUNCTION CREATE_POLICY_SCRIPT(
  POLICY_NAME      IN VARCHAR2,
  PREFNAME_PREFIX IN VARCHAR2 DEFAULT NULL
) RETURN CLOB
IS
  X CLOB;
  IDX DR_DEF.IDX_REC;
BEGIN
  DRVUTL.SETINVOKER;
  IDX := DRIXMD.GETINDEXREC(POLICY_NAME,
                            F_ISPOLICY=>DRIXMD.POL_INDEX_OR_POLICY);

 
  IF (DRIXMD.CHKINDEXOPTION(IDX.IDX_ID, 'E') = 1) THEN
    DRUE.PUSH(DRIG.EE_DOCSVC_ENT_POLICY);
    RAISE DR_DEF.TEXTILE_ERROR;
  END IF;
  DBMS_LOB.CREATETEMPORARY(X, TRUE, DBMS_LOB.CALL);
  DRIREPM.CREATE_POLICY_SCRIPT(POLICY_NAME, X, PREFNAME_PREFIX);
  DRVUTL.CLEARINVOKER;
  RETURN X; 
EXCEPTION
  WHEN DR_DEF.TEXTILE_ERROR THEN
    DRUE.RAISE;
  WHEN OTHERS THEN
    DRUE.TEXT_ON_STACK(SQLERRM, 'ctx_report.create_policy_script');
    DRUE.RAISE;
END CREATE_POLICY_SCRIPT;



PROCEDURE INDEX_SIZE(
  INDEX_NAME    IN VARCHAR2,
  REPORT        IN OUT NOCOPY CLOB,
  PART_NAME     IN VARCHAR2 DEFAULT NULL,
  REPORT_FORMAT IN VARCHAR2 DEFAULT FMT_TEXT
) IS
  IDX DR_DEF.IDX_REC;
BEGIN
  DRVUTL.SETINVOKER;
  IDX := DRIXMD.GETINDEXREC(INDEX_NAME);
  DRIREPZ.INDEX_SIZE(INDEX_NAME, REPORT, PART_NAME, REPORT_FORMAT);
  DRVUTL.CLEARINVOKER;
EXCEPTION
  WHEN DR_DEF.TEXTILE_ERROR THEN
    DRUE.RAISE;
  WHEN OTHERS THEN
    DRUE.TEXT_ON_STACK(SQLERRM, 'ctx_report.index_size');
    DRUE.RAISE;
END INDEX_SIZE;



FUNCTION INDEX_SIZE(
  INDEX_NAME    IN VARCHAR2,
  PART_NAME     IN VARCHAR2 DEFAULT NULL,
  REPORT_FORMAT IN VARCHAR2 DEFAULT FMT_TEXT
) RETURN CLOB
IS
  X CLOB;
  IDX DR_DEF.IDX_REC;
BEGIN
  DRVUTL.SETINVOKER;
  IDX := DRIXMD.GETINDEXREC(INDEX_NAME);
  DBMS_LOB.CREATETEMPORARY(X, TRUE, DBMS_LOB.CALL);
  DRIREPZ.INDEX_SIZE(INDEX_NAME, X, PART_NAME, REPORT_FORMAT);
  DRVUTL.CLEARINVOKER;
  RETURN X; 
EXCEPTION
  WHEN DR_DEF.TEXTILE_ERROR THEN
    DRUE.RAISE;
  WHEN OTHERS THEN
    DRUE.TEXT_ON_STACK(SQLERRM, 'ctx_report.index_size');
    DRUE.RAISE;
END INDEX_SIZE;



PROCEDURE INDEX_STATS(
  INDEX_NAME    IN VARCHAR2,
  REPORT        IN OUT NOCOPY CLOB,
  PART_NAME     IN VARCHAR2 DEFAULT NULL,
  FRAG_STATS    IN BOOLEAN DEFAULT TRUE,
  LIST_SIZE     IN NUMBER  DEFAULT 100,
  REPORT_FORMAT IN VARCHAR2 DEFAULT FMT_TEXT,
  STAT_TYPE  IN VARCHAR2 DEFAULT NULL
)
IS
  IDX DR_DEF.IDX_REC;
  IXP DR_DEF.IXP_REC;
  L_FRGS    NUMBER := 1;
  L_NUM_FMT NUMBER;
  L_STAT_TYPE NUMBER := 0;
BEGIN
  IF (REPORT_FORMAT NOT IN ('TEXT','XML')) THEN
     DRUE.PUSH(DRIG.GU_LIST_ERROR, 'REPORT_FORMAT','XML,TEXT');
     RAISE DR_DEF.TEXTILE_ERROR;
  END IF;

  DRVUTL.SETINVOKER;
  IDX := DRIXMD.GETINDEXREC(INDEX_NAME);
  IXP := DRIXMD.GETPARTITIONREC(PART_NAME, IDX);

  IF (LIST_SIZE IS NULL) THEN
    DRUE.PUSH(DRIG.GU_REQUIRED_NULL, 'LIST_SIZE');
    RAISE DR_DEF.TEXTILE_ERROR;
  END IF;

  IF (LIST_SIZE > 1000 OR LIST_SIZE < 5) THEN
    DRUE.PUSH(DRIG.GU_RANGE_ERROR, 'LIST_SIZE', 5, 100);
    RAISE DR_DEF.TEXTILE_ERROR;
  END IF;


  IF (STAT_TYPE = 'EST_SLOWEST_QUERIES') THEN
    IF ((IDX.IDX_TYPE != DRIXMD.IDX_TYPE_CONTEXT) AND
        (IDX.IDX_TYPE != DRIXMD.IDX_TYPE_CTXCAT)) THEN
          DRUE.PUSH(DRIG.GU_IDXTYPE_NOT_SUP);
          RAISE DR_DEF.TEXTILE_ERROR;
    END IF;      
  ELSE
    IF (IDX.IDX_TYPE != DRIXMD.IDX_TYPE_CONTEXT) THEN
      DRUE.PUSH(DRIG.GU_IDXTYPE_NOT_SUP);
      RAISE DR_DEF.TEXTILE_ERROR;
    END IF;
  END IF;



   IF STAT_TYPE IS NOT NULL THEN
     IF IDX.IDX_OPTION NOT LIKE '%Z%' THEN
      DRUE.PUSH(DRIG.QS_NEED_TO_BE_ENABLED);
      RAISE DR_DEF.TEXTILE_ERROR;
    END IF;

     IF STAT_TYPE = 'EST_FRAG_STATS' THEN
       L_STAT_TYPE := 1;
     ELSE IF STAT_TYPE = 'EST_FREQUENT_TOKENS' THEN
       L_STAT_TYPE := 2;
     ELSE IF STAT_TYPE = 'EST_TOKENS_TO_OPTIMIZE' THEN
       L_STAT_TYPE := 3;
     ELSE IF STAT_TYPE = 'EST_SLOWEST_QUERIES' THEN
       L_STAT_TYPE := 4;
     ELSE

       DRUE.PUSH(DRIG.QS_INVALID_STATTYPE, STAT_TYPE);
       RAISE DR_DEF.TEXTILE_ERROR;
     END IF;
     END IF;
     END IF;
     END IF;
   END IF;

  IF (NOT FRAG_STATS) THEN L_FRGS := 0; END IF;
 
  IF (REPORT IS NULL) THEN
    DBMS_LOB.CREATETEMPORARY(REPORT, TRUE, DBMS_LOB.SESSION);
  ELSE
    DBMS_LOB.TRIM(REPORT, 0);
  END IF;

  IF (REPORT_FORMAT = 'XML') THEN
    L_NUM_FMT := 1;
  ELSE
    L_NUM_FMT := 0;
  END IF;

  DRVDISP.EXECASOWN_CLOB(IDX.IDX_OWNER#,IDX.IDX_OWNER,
                         IDX.IDX_NAME, IXP.IXP_NAME,
                         DRILIST.CMD_REPORT_STATS, REPORT,
                         L_FRGS, LIST_SIZE, L_NUM_FMT, L_STAT_TYPE);
  DRVUTL.CLEARINVOKER;
EXCEPTION
  WHEN DR_DEF.TEXTILE_ERROR THEN
    DRUE.RAISE;
  WHEN OTHERS THEN
    DRUE.TEXT_ON_STACK(SQLERRM, 'ctx_report.index_stats');
    DRUE.RAISE;
END INDEX_STATS;



PROCEDURE TOKEN_INFO(
  INDEX_NAME      IN VARCHAR2,
  REPORT          IN OUT NOCOPY CLOB,
  TOKEN           IN VARCHAR2,
  TOKEN_TYPE      IN NUMBER,
  PART_NAME       IN VARCHAR2 DEFAULT NULL,
  RAW_INFO        IN BOOLEAN  DEFAULT FALSE,
  DECODED_INFO    IN BOOLEAN  DEFAULT TRUE,
  REPORT_FORMAT   IN VARCHAR2 DEFAULT FMT_TEXT
) IS
  IDX DR_DEF.IDX_REC;
BEGIN
  IF (REPORT_FORMAT NOT IN ('TEXT','XML')) THEN
     DRUE.PUSH(DRIG.GU_LIST_ERROR, 'REPORT_FORMAT','XML,TEXT');
     RAISE DR_DEF.TEXTILE_ERROR;
  END IF;

  IF (REPORT IS NULL) THEN
    DBMS_LOB.CREATETEMPORARY(REPORT, TRUE, DBMS_LOB.SESSION);
  END IF;

  DRVUTL.SETINVOKER;
  IDX := DRIXMD.GETINDEXREC(INDEX_NAME);

  INT_TOKEN_INFO(INDEX_NAME, REPORT, TOKEN, TOKEN_TYPE, PART_NAME,
                   RAW_INFO, DECODED_INFO, REPORT_FORMAT);
  DRVUTL.CLEARINVOKER;
EXCEPTION
  WHEN DR_DEF.TEXTILE_ERROR THEN
    DRUE.RAISE;
  WHEN OTHERS THEN
    DRUE.TEXT_ON_STACK(SQLERRM, 'ctx_report.token_info');
    DRUE.RAISE;
END TOKEN_INFO;



FUNCTION TOKEN_INFO(
  INDEX_NAME      IN VARCHAR2,
  TOKEN           IN VARCHAR2,
  TOKEN_TYPE      IN NUMBER,
  PART_NAME       IN VARCHAR2 DEFAULT NULL,
  RAW_INFO        IN VARCHAR2 DEFAULT 'N',
  DECODED_INFO    IN VARCHAR2 DEFAULT 'Y',
  REPORT_FORMAT   IN VARCHAR2 DEFAULT FMT_TEXT
) RETURN CLOB
IS
  X CLOB;
  L_PRD BOOLEAN := FALSE;
  L_DI  BOOLEAN := TRUE;
  IDX DR_DEF.IDX_REC;
BEGIN
  IF (REPORT_FORMAT NOT IN ('TEXT','XML')) THEN
     DRUE.PUSH(DRIG.GU_LIST_ERROR, 'REPORT_FORMAT','XML,TEXT');
     RAISE DR_DEF.TEXTILE_ERROR;
  END IF;

  DRVUTL.SETINVOKER;
  IDX := DRIXMD.GETINDEXREC(INDEX_NAME);

  IF (UPPER(RAW_INFO) IN ('Y', 'YES', 'T', 'TRUE')) THEN
    L_PRD := TRUE;
  END IF;
  IF (UPPER(DECODED_INFO) IN ('N', 'NO', 'F', 'FALSE')) THEN
    L_DI := FALSE;
  END IF;

  DBMS_LOB.CREATETEMPORARY(X, TRUE, DBMS_LOB.CALL);
  INT_TOKEN_INFO(INDEX_NAME, X, TOKEN, TOKEN_TYPE, PART_NAME,
                 L_PRD, L_DI, REPORT_FORMAT);
  DRVUTL.CLEARINVOKER;
  RETURN X;
EXCEPTION
  WHEN DR_DEF.TEXTILE_ERROR THEN
    DRUE.RAISE;
  WHEN OTHERS THEN
    DRUE.TEXT_ON_STACK(SQLERRM, 'ctx_report.token_info');
    DRUE.RAISE;
END TOKEN_INFO;



FUNCTION TOKEN_TYPE(
  INDEX_NAME IN VARCHAR2,
  TYPE_NAME  IN VARCHAR2
) RETURN NUMBER
IS
  L_NAME VARCHAR2(256) := LTRIM(RTRIM(UPPER(TYPE_NAME)));
  L_SEC  VARCHAR2(256) := NULL;
  L_MOD  NUMBER := 0;
  SEC    DR_DEF.SEC_TAB;
  IDX    DR_DEF.IDX_REC;
 BEGIN
  IF (L_NAME = 'TEXT') THEN
    RETURN TOKEN_TYPE_TEXT;
  ELSIF (L_NAME = 'THEME') THEN
    RETURN TOKEN_TYPE_THEME;
  ELSIF (L_NAME = 'ZONE SEC') THEN
    RETURN TOKEN_TYPE_ZONE_SEC;
  ELSIF (L_NAME = 'ATTR TEXT') THEN
    RETURN TOKEN_TYPE_ATTR_TEXT;
  ELSIF (L_NAME = 'ATTR SEC') THEN
    RETURN TOKEN_TYPE_ATTR_SEC;
  ELSIF (L_NAME = 'PREFIX') THEN
    RETURN TOKEN_TYPE_PREFIX;
  ELSIF (L_NAME = 'PATH SEC') THEN
    RETURN TOKEN_TYPE_PATH_SEC;
  ELSIF (L_NAME = 'PATH ATTR') THEN
    RETURN TOKEN_TYPE_PATH_ATTR;
  ELSIF (L_NAME = 'STEM') THEN
    RETURN TOKEN_TYPE_STEM;
  ELSIF (L_NAME = 'ATTR TEXT PREFIX') THEN
    RETURN TOKEN_TYPE_ATTR_TXT_PFIX;
  ELSIF (L_NAME = 'ATTR TEXT STEM') THEN
    RETURN TOKEN_TYPE_ATTR_TXT_STEM;
  END IF;

  DRVUTL.SETINVOKER;

  IDX := DRIXMD.GETINDEXREC(INDEX_NAME);

 

  IF (L_NAME LIKE 'FIELD%' OR L_NAME LIKE 'MDATA%' OR L_NAME LIKE 'NDATA%')
  THEN
    L_NAME := LTRIM(SUBSTR(L_NAME, 7));
    IF (L_NAME LIKE '%TEXT') THEN
      L_SEC := RTRIM(SUBSTR(L_NAME,1,LENGTH(L_NAME) - 5));
    ELSIF (L_NAME LIKE '%PREFIX') THEN
      L_SEC := RTRIM(SUBSTR(L_NAME,1,LENGTH(L_NAME) - 7));
      L_MOD := 600;
    ELSIF (L_NAME LIKE '%STEM') THEN
      L_SEC := RTRIM(SUBSTR(L_NAME,1,LENGTH(L_NAME) - 5));
      L_MOD := 900;
    ELSE
      L_SEC := L_NAME;
      L_MOD := 0;
    END IF;

    L_SEC := UPPER(RTRIM(LTRIM(L_SEC,'"'),'"'));
    DRISGP.LOADSECTIONMD(IDX.IDX_ID, TRUE, SEC);
    FOR I IN 1..SEC.COUNT LOOP
      IF (SEC(I).SEC_NAME = L_SEC) THEN
        RETURN SEC(I).SEC_FID + L_MOD;
      END IF;
    END LOOP;
  END IF;

 

  DRUE.PUSH(DRIG.PF_INV_ATTRIBUTE_VALUE, 'TYPE_NAME', TYPE_NAME);
  RAISE DR_DEF.TEXTILE_ERROR;
 
  DRVUTL.CLEARINVOKER;
 
  RETURN 0;

EXCEPTION
  WHEN DR_DEF.TEXTILE_ERROR THEN
    DRUE.RAISE;
  WHEN OTHERS THEN
    DRUE.TEXT_ON_STACK(SQLERRM, 'ctx_report.token_type');
    DRUE.RAISE;
END TOKEN_TYPE;


END CTX_REPORT;
/