home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1996 February / PCWK0296.iso / po7_win / db / rdbms71 / readpipe.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-07  |  6.0 KB  |  232 lines

  1. #ifdef RCSID
  2. static char *RCSid = 
  3.    "$Header: readpipe.c 7010300.1 94/02/24 18:40:31 snataraj Generic<base> $ ";
  4. #endif /* RCSID */
  5.  
  6. /* Copyright (c) 1991 by Oracle Corporation */
  7. /*
  8.    NAME
  9.      readpipe.c - read a server named pipe
  10.    NOTES
  11.      described in ORACLE7 Server Application Developer's Guide
  12.    MODIFIED   (MM/DD/YY)
  13.     emendez    02/02/94 -  Fix for bug 157576
  14.     gdoherty   01/31/94 -  make oci header inclusion for ansi or k+r adaptive
  15.     rkooi      12/15/92 -  add some comments 
  16.     tssmith      12/15/92 -  Added break in for(;;) loop 
  17.     tssmith      12/12/92 -  Creation 
  18. */
  19.  
  20. /*
  21.  *  readpipe.c
  22.  *
  23.  *  This OCI program demonstrates how to read messages from
  24.  *  a named pipe.  This program can be run in
  25.  *  a window or terminal session, and be used to print messages
  26.  *  from a PL/SQL source program (an anonymous block or a
  27.  *  stored procedure).
  28.  *
  29.  *  This is very useful in debugging PL/SQL programs.
  30.  *
  31.  *  First, you must create a PL/SQL package and package body that packs
  32.  *  your message(s) and sends them to a named pipe.
  33.  *  In the example below, two 'put' procedures are implemented,
  34.  *  overloaded by type: VARCHAR2 and NUMBER.  This you can extend
  35.  *  as required for additional types.
  36.  *  
  37.  *  Store this package in the server in an appropriate schema,
  38.  *  and grant execute privilege on it to the users who require it.
  39.  *
  40.  *  You will need to grant execute privilege on the dbms_pipe package
  41.  *  to the owner of the plsdbg package below.
  42.  *
  43.  *  Note that this example uses only a single named pipe.  It could
  44.  *  be confusing if more than one PL/SQL program were writing to
  45.  *  the same pipe (unless some identifying protocol is established).
  46.  *  It would certainly be confusing if several OCI programs like
  47.  *  the one below were reading the same pipe.
  48.  *
  49.  *  Here is the example package:
  50.  *  
  51.  *    create or replace package plsdbg as
  52.  *      -- the procedure put is overloaded for varchar strings
  53.  *      -- and numbers.  extend as needed.   
  54.  *        procedure put(info varchar2);
  55.  *        procedure put(n number);
  56.  *    end;
  57.  *    /
  58.  *  
  59.  *    create or replace package body plsdbg as
  60.  *  
  61.  *        procedure put(info varchar2) is
  62.  *            status integer;  -- ret. val. required for the 
  63.  *                             -- send_message function, not used here
  64.  *        begin
  65.  *            dbms_pipe.pack_message(info);
  66.  *            status := dbms_pipe.send_message('ora$plsql_debug');
  67.  *        end;
  68.  *  
  69.  *        procedure put(n number) is
  70.  *            chr    varchar2(44);
  71.  *            status integer;
  72.  *        begin
  73.  *            chr := to_char(n);
  74.  *            dbms_pipe.pack_message(chr);
  75.  *            status :=  dbms_pipe.send_message('ora$plsql_debug');
  76.  *        end;
  77.  *    end;
  78.  *    /
  79.  *
  80.  *  In a PL/SQL program, you call plsdbg to write messages to the
  81.  *  pipe 'ora$plsql_debug' like this:
  82.  *  ...
  83.  *  declare
  84.  *    my_var   integer;
  85.  *    ...
  86.  *  begin
  87.  *    my_var := 42;
  88.  *    ...   -- program procedes until debug output is needed
  89.  *    plsdbg.put('Hmm, my_var is--');
  90.  *    plsdbg.put(my_var);
  91.  *          -- and the OCI program reading ora$plsql_debug will
  92.  *          -- print the text message, and the value of my_var
  93.  *    ...
  94.  */
  95.  
  96. #include <stdio.h>
  97. #include <string.h>
  98.  
  99. /*  These header files must be included for the
  100.     type information, and #defined constants. */
  101. #include <oratypes.h>
  102. #include <ocidfn.h>
  103. #ifdef __STDC__
  104. #include <ociapr.h>
  105. #else
  106. #include <ocikpr.h>
  107. #endif
  108.  
  109. /* demo constants and structs */
  110. #include <ocidem.h>
  111.  
  112. /* Declare the CDA, LDA, and HDA. */
  113. Cda_Def lda;
  114. ub1     hda[HDA_SIZE];
  115. Cda_Def cda;
  116.  
  117. /* Define a string that holds the anonymous PL/SQL block.
  118.    The block calls the DBMS_PIPE procedures to get messages
  119.    written to the pipe named ora$plsql_debug. */
  120.  
  121. #define GETNEXTITEM "\
  122. declare\
  123.   s integer;\
  124.   chr varchar2(200);\
  125. begin\
  126.   chr := '';\
  127.   s := dbms_pipe.receive_message('ora$plsql_debug');\
  128.   if s = 0 then\
  129.     dbms_pipe.unpack_message(chr);\
  130.   end if;\
  131.   :status := s;\
  132.   :retval := chr;\
  133. end;"
  134.  
  135. /* Error-handling function */
  136. void errrpt();
  137.  
  138.  
  139. main(argc, argv)
  140. sword argc;
  141. text **argv;
  142. {
  143.     text username[128];
  144.     ub1 retval[132];
  145.     sword  status;
  146.  
  147. /* Prepare username/password, from command line or
  148.    else use scott/tiger as the default if none given on
  149.    the command line. */
  150.  
  151.     if (argc > 1)
  152.         strncpy((char *) username, (char *) argv[1],
  153.                 (sword) sizeof (username) - 1);
  154.     else
  155.         strcpy((char *) username, "SCOTT/TIGER");
  156.  
  157. /* Connect to ORACLE. */
  158.     if (orlon(&lda, hda, username, -1,
  159.               (text *) 0, -1, 0))
  160.     {
  161.         printf("Cannot connect as %s. Exiting...\n", username);
  162.         exit(1);
  163.     }
  164.     else
  165.         printf("connected\n");
  166.  
  167. /* Open the cursor -- must quit if we cannot. */
  168.     if (oopen(&cda, &lda, (text *) 0, -1, -1, (text *) 0, -1))
  169.     {
  170.         printf("Error opening cursor.  Exiting...\n");
  171.         exit(1);
  172.     }
  173.  
  174. /* Parse the anonymous PL/SQL block. */
  175.     if (oparse(&cda, (text *) GETNEXTITEM, 
  176.                (sb4) -1, 0, (ub4) 2))
  177.     {
  178.         errrpt();
  179.         exit(1);
  180.     }
  181.  
  182. /* Bind the status program variable. */
  183.     if (obndrv(&cda, (text *) ":status", -1, (ub1 *) &status,
  184.                (sword) sizeof (sword), SQLT_INT,
  185.                -1, (sb2 *) 0, (text *) 0, -1, -1))
  186.     {
  187.         errrpt();
  188.         exit(1);
  189.     }
  190.  
  191. /* Bind the return string (retval). */
  192.     if (obndrv(&cda, (text *) ":retval", -1, (ub1 *) retval,
  193.                (sword) sizeof (retval), SQLT_STR,
  194.                -1, (sb2 *) 0, (text *) 0, -1, -1))
  195.     {
  196.         errrpt();
  197.         exit(1);
  198.     }
  199.  
  200. /* Loop to look for print messages on the pipe */
  201.     printf("listening...\n");
  202.     for (;;)
  203.     {
  204.         if (oexec(&cda))
  205.         {
  206.             errrpt();
  207.             break;
  208.         }
  209.  
  210.         if (status != 0)
  211.             printf("Abnormal pipe status: %d\n\r", status);
  212.         else
  213.             printf("%s\n\r", retval);
  214.     }
  215. }
  216.  
  217.  
  218. /* Report errors. */
  219. void errrpt()
  220. {
  221.     sword rv;
  222.     text msg[1024];
  223.  
  224. /* use oerhms to get error messages longer than 70 characters */
  225.     rv = oerhms(&lda, cda.rc, msg, (sword) sizeof (msg));
  226.     printf("ORACLE ERROR\n");
  227.     printf("%.*s\n", rv, msg);
  228. }
  229.  
  230.  
  231.  
  232.