home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1996 February / PCWK0296.iso / po7_win / db / rdbms71 / dbmspipe.sql < prev    next >
Encoding:
Text File  |  1994-08-07  |  15.3 KB  |  385 lines

  1. rem 
  2. rem $Header: dbmspipe.sql 7010300.1 94/02/24 18:25:49 snataraj Generic<base> $ 
  3. rem 
  4. Rem  Copyright (c) 1991 by Oracle Corporation 
  5. Rem    NAME
  6. Rem      dbmspipe.sql - send and receive from dbms "pipes"
  7. Rem    DESCRIPTION
  8. Rem      Allow sessions to pass information between them through 
  9. Rem      named SGA memory "pipes"
  10. Rem    RETURNS
  11. Rem 
  12. Rem    NOTES
  13. Rem      The procedural option is needed to use this facility.
  14. Rem      
  15. Rem    MODIFIED   (MM/DD/YY)
  16. Rem     adowning   02/02/94 -  split file into public / private binary files
  17. Rem     dsdaniel   07/09/93 -  dbms_defer longifaction for async rep
  18. Rem     rkooi      10/18/92 -  better comments 
  19. Rem     rkooi      08/20/92 -  comments and cleanup 
  20. Rem     rkooi      05/18/92 -  change comment 
  21. Rem     rkooi      04/28/92 -  change put to pack, etc. 
  22. Rem     rkooi      04/25/92 -  Creation 
  23.  
  24. REM ********************************************************************
  25. REM THIS PACKAGE MUST NOT BE MODIFIED BY THE CUSTOMER.  DOING SO
  26. REM COULD CAUSE INTERNAL ERRORS AND SECURITY VIOLATIONS IN THE
  27. REM RDBMS.  SPECIFICALLY, THE PSD* ROUTINES MUST NOT BE CALLED
  28. REM DIRECTLY BY ANY CLIENT AND MUST REMAIN PRIVATE TO THE PACKAGE BODY.
  29. REM ********************************************************************
  30.  
  31. create or replace package dbms_pipe is
  32.  
  33.   ------------
  34.   --  OVERVIEW
  35.   --
  36.   --  This package provides a DBMS "pipe" service which allows messages
  37.   --  to be sent between sessions.
  38.   --
  39.   --  The metaphor is similar to UNIX pipes:  you can do
  40.   --      dbms_pipe.send_message(<pipename>)
  41.   --      dbms_pipe.receive_message(<pipename>)
  42.   --  which will cause a message to be sent or received.  You do
  43.   --      dbms_pipe.pack_message(<varchar2>|<number>|<date>)
  44.   --  to pack an item into a static buffer (which will then be sent with 
  45.   --  the "send_message" call), and
  46.   --      dbms_pipe.unpack_message(<varchar2>|<number>|<date>)
  47.   --  to get an item out of the static buffer (which is filled by the 
  48.   --  "receive_message" call).
  49.   --
  50.   --  Pipes operate independently of transactions.  They also operate
  51.   --  asynchronously.  There can be multiple readers and writers of the
  52.   --  same pipe.
  53.   --
  54.   --  Pipes only operate between sessions in the same instance.
  55.   --
  56.   --  Pipes automatically come into existence the first time they are
  57.   --  referenced.  They effectively disappear when they contain no more
  58.   --  data (some overhead remains in the SGA until it gets aged out).
  59.   --  Pipes take up space in the SGA (see "maxpipesize" parameter to 
  60.   --  "send_message").
  61.  
  62.  
  63.   --------
  64.   --  USES
  65.   --
  66.   --  The pipe functionality has several potential applications:
  67.   --
  68.   --    o External service interface.  You can provide the ability to
  69.   --      communicate with (user-written) services that are external to the
  70.   --      RDBMS.  This can be done in a (effectively) multi-threaded manner
  71.   --      so that several instances of the service can be executing
  72.   --      simultaneously. Additionally, the services are available
  73.   --      asynchronously - the requestor of the service need not block
  74.   --      awaiting a reply.  The requestor can check (with or without
  75.   --      timeout) at a later time.  The service can be written in any
  76.   --      of the 3GL languages that ORACLE supports, not just C.  See
  77.   --      example below.
  78.   --    o Independent transactions.  The pipe can be used to communicate
  79.   --      to a separate session which can perform an operation in an
  80.   --      independent transaction (such as logging an attempted security 
  81.   --      violation detected by a trigger).
  82.   --    o Alerters (non-transactional).  You can post another process
  83.   --      without requiring the waiting process to poll.  If an "after-row"
  84.   --      or "after-statement" trigger were to alert an application, then
  85.   --      the application would treat this alert as an indication that
  86.   --      the data probably changed.  The application would then go read
  87.   --      the data to get the current value.  Since this is an "after" 
  88.   --      trigger, the application would want to do a "select for update"
  89.   --      to make sure it read the correct data.
  90.   --    o Debugging.  Triggers and/or stored procedures can send debugging
  91.   --      information to a pipe.  Another session can keep reading out
  92.   --      of the pipe and displaying it on the screen or writing it 
  93.   --      out to a file.
  94.   --    o Concentrator. Useful for multiplexing large numbers of users
  95.   --      over a fewer number of network connections, or improving
  96.   --      performance by concentrating several user-transactions into
  97.   --      one dbms-transaction.
  98.  
  99.  
  100.   ------------
  101.   --  SECURITY
  102.   --
  103.   --  Security can be achieved by use of 'grant execute', and by writing cover
  104.   --  packages that only expose particular features or pipenames to particular
  105.   --  users or roles.
  106.  
  107.  
  108.   ------------
  109.   --  EXAMPLES
  110.   --
  111.   --  External service interface
  112.   ------------------------------
  113.   --
  114.   --  Put the user-written 3GL code into an OCI or Precompiler program.
  115.   --  The program connects to the database and executes PL/SQL code to read
  116.   --  its request from the pipe, computes the result, and then executes
  117.   --  PL/SQL code to send the result on a pipe back to the requestor.
  118.   --  Below is an example of a stock service request.
  119.   --  
  120.   --  The recommended sequence for the arguments to pass on the pipe
  121.   --  for all service requests is
  122.   --  
  123.   --      protocol_version    varchar2    - '1', 10 bytes or less
  124.   --      returnpipe        varchar2     - 30 bytes or less
  125.   --      service        varchar2     - 30 bytes or less
  126.   --      arg1            varchar2/number/date
  127.   --         ...
  128.   --      argn            varchar2/number/date
  129.   --  
  130.   --  The recommended format for returning the result is
  131.   --  
  132.   --      success        varchar2    - 'SUCCESS' if OK,
  133.   --                            otherwise error message
  134.   --      arg1            varchar2/number/date
  135.   --         ...
  136.   --      argn            varchar2/number/date
  137.   --  
  138.   --  
  139.   --  The "stock price request server" would do, using OCI or PRO* (in
  140.   --  pseudo-code):
  141.   --  
  142.   --    <loop forever>
  143.   --        begin dbms_stock_server.get_request(:stocksymbol); end;
  144.   --        <figure out price based on stocksymbol (probably from some radio
  145.   --          signal), set error if can't find such a stock>
  146.   --        begin dbms_stock_server.return_price(:error, :price); end;
  147.   --  
  148.   --  A client would do:
  149.   --
  150.   --      begin :price := stock_request('YOURCOMPANY'); end;
  151.   --      
  152.   --  The stored procedure, dbms_stock_server, which is called by the 
  153.   --  "stock price request server" above is:
  154.   --  
  155.   --    create or replace package dbms_stock_server is
  156.   --      procedure get_request(symbol out varchar2);
  157.   --      procedure return_price(errormsg in varchar2, price in varchar2);
  158.   --    end;
  159.   --  
  160.   --    create  or replace package body dbms_stock_server is
  161.   --      returnpipe    varchar2(30);
  162.   --  
  163.   --      procedure returnerror(reason varchar2) is
  164.   --        s integer;
  165.   --      begin
  166.   --        dbms_pipe.pack_message(reason);
  167.   --        s := dbms_pipe.send_message(returnpipe);
  168.   --        if s <> 0 then
  169.   --          raise_application_error(-20000, 'Error:' || to_char(s) ||
  170.   --            ' sending on pipe');
  171.   --        end if;
  172.   --      end;
  173.   --  
  174.   --      procedure get_request(symbol out varchar2) is
  175.   --        protocol_version varchar2(10);
  176.   --        s               integer;
  177.   --        service           varchar2(30);
  178.   --      begin
  179.   --        s := dbms_pipe.receive_message('stock_service');
  180.   --        if s <> 0 then
  181.   --          raise_application_error(-20000, 'Error:' || to_char(s) ||
  182.   --            'reading pipe');
  183.   --        end if;
  184.   --        dbms_pipe.unpack_message(protocol_version);
  185.   --        if protocol_version <> '1' then
  186.   --          raise_application_error(-20000, 'Bad protocol: ' || 
  187.   --            protocol_version);
  188.   --        end if;
  189.   --        dbms_pipe.unpack_message(returnpipe);
  190.   --        dbms_pipe.unpack_message(service);
  191.   --        if service != 'getprice' then
  192.   --          returnerror('Service ' || service || ' not supported');
  193.   --        end if;
  194.   --        dbms_pipe.unpack_message(symbol);
  195.   --      end;
  196.   --  
  197.   --      procedure return_price(errormsg in varchar2, price in varchar2) is
  198.   --        s integer;
  199.   --      begin
  200.   --        if errormsg is null then
  201.   --          dbms_pipe.pack_message('SUCCESS');
  202.   --          dbms_pipe.pack_message(price);
  203.   --        else
  204.   --          dbms_pipe.pack_message(errormsg);
  205.   --        end if;
  206.   --        s := dbms_pipe.send_message(returnpipe);
  207.   --        if s <> 0 then
  208.   --          raise_application_error(-20000, 'Error:'||to_char(s)||
  209.   --            ' sending on pipe');
  210.   --        end if;
  211.   --      end;
  212.   --    end;
  213.   --  
  214.   --  
  215.   --  The procedure called by the client is:
  216.   --  
  217.   --    create or replace function stock_request (symbol varchar2) 
  218.   --        return varchar2 is
  219.   --      s        integer;
  220.   --      price    varchar2(20);
  221.   --      errormsg varchar2(512);
  222.   --    begin
  223.   --      dbms_pipe.pack_message('1');  -- protocol version
  224.   --      dbms_pipe.pack_message(dbms_pipe.unique_session_name); -- return pipe
  225.   --      dbms_pipe.pack_message('getprice');
  226.   --      dbms_pipe.pack_message(symbol);
  227.   --      s := dbms_pipe.send_message('stock_service');
  228.   --      if s <> 0 then
  229.   --        raise_application_error(-20000, 'Error:'||to_char(s)||
  230.   --          ' sending on pipe');
  231.   --      end if;
  232.   --      s := dbms_pipe.receive_message(dbms_pipe.unique_session_name);
  233.   --      if s <> 0 then
  234.   --        raise_application_error(-20000, 'Error:'||to_char(s)||
  235.   --          ' receiving on pipe');
  236.   --      end if;
  237.   --      dbms_pipe.unpack_message(errormsg);
  238.   --      if errormsg <> 'SUCCESS' then
  239.   --        raise_application_error(-20000, errormsg);
  240.   --      end if;
  241.   --      dbms_pipe.unpack_message(price);
  242.   --      return price;
  243.   --    end;
  244.   --  
  245.   --  You would typically only grant execute on 'dbms_stock_service' to 
  246.   --  the stock service application server, and would only grant execute 
  247.   --  on 'stock_request' to those users allowed to use the service.
  248.  
  249.  
  250.   ---------------------
  251.   --  SPECIAL CONSTANTS
  252.   --
  253.   maxwait   constant integer := 86400000; /* 1000 days */ 
  254.   --  The maximum time to wait attempting to send or receive a message
  255.  
  256.  
  257.   ----------------------------
  258.   --  PROCEDURES AND FUNCTIONS
  259.   --
  260.   procedure pack_message(item in varchar2);
  261.   procedure pack_message(item in number);
  262.   procedure pack_message(item in date);
  263.   procedure pack_message_raw(item in raw);
  264.   procedure pack_message_rowid(item in rowid);
  265.   --  Pack an item into the message buffer
  266.   --  Input parameters:
  267.   --    item
  268.   --      Item to pack into the local message buffer.
  269.   --  Exceptions:
  270.   --    ORA-06558 generated if message buffer overflows (currently 4096
  271.   --    bytes).  Each item in the buffer takes one byte for the type,
  272.   --    two bytes for the length, plus the actual data.  There is also one
  273.   --    byte needed to terminate the message.
  274.   --
  275.   procedure unpack_message(item out varchar2);
  276.   procedure unpack_message(item out number);
  277.   procedure unpack_message(item out date);
  278.   procedure unpack_message_raw(item out raw);
  279.   procedure unpack_message_rowid(item out rowid);
  280.   --  Unpack an item from the local message buffer
  281.   --  Output parameters:
  282.   --    item
  283.   --      The argument to receive the next unpacked item from the local 
  284.   --      message buffer.
  285.   --  Exceptions:
  286.   --    ORA-06556 or 06559 are generated if the buffer contains
  287.   --    no more items, or if the item is not of the same type as that
  288.   --    requested (see 'next_item_type' below).
  289.   --
  290.   function next_item_type return integer;
  291.   --  Get the type of the next item in the local message buffer
  292.   --  Return value:
  293.   --    Type of next item in buffer:
  294.   --        0    no more items
  295.   --        9    varchar2
  296.   --        6    number
  297.   --       11    rowid
  298.   --       12    date
  299.   --       23    raw
  300.   function send_message(pipename in varchar2, 
  301.                         timeout in integer default maxwait,
  302.                         maxpipesize in integer default 8192)
  303.     return integer;
  304.   --  Send a message on the named pipe.  The message is contained in the
  305.   --    local message buffer which was filled with calls to 'pack_message'.
  306.   --  Input parameters:
  307.   --    pipename
  308.   --      Name of pipe to place the message on.  The message is copied 
  309.   --      from the local buffer which can be filled by the "pack_message"
  310.   --      routine.  WARNING:  Do not use pipe names beginning with 'ORA$'.
  311.   --      These names are reserved for use by procedures provided by 
  312.   --      Oracle Corporation.  Pipename should not be longer than 128 bytes,
  313.   --      and is case_insensitive.
  314.   --    timeout
  315.   --      Time to wait while attempting to place a message on a pipe, in
  316.   --      seconds (see return codes below).
  317.   --    maxpipesize
  318.   --      Maximum allowed size for the pipe.  The total size of all the
  319.   --      messages on the pipe cannot exceed this amount.  If this message 
  320.   --      would exceed this amount the call will block.  The maxpipesize 
  321.   --      for a pipe becomes part of the pipe and persists for the lifetime
  322.   --      of the pipe.  Callers of send_message with larger values will 
  323.   --      cause the maxpipesize to be increased.  Callers with a smaller 
  324.   --      value will just use the larger value.  The specification of
  325.   --      maxpipesize here allows us to avoid the use of a "open_pipe" call.
  326.   --  Return value:
  327.   --    0 - Success
  328.   --    1 - Timed out (either because can't get lock on pipe or    pipe stays 
  329.   --        too full)
  330.   --    3 - Interrupted
  331.   --
  332.   function receive_message(pipename in varchar2,
  333.                            timeout in integer default maxwait)
  334.     return integer;
  335.   --  Receive a message from the named pipe.  Copy the message into the
  336.   --    local message buffer.  Use 'unpack_message' to access the
  337.   --    individual items in the message.
  338.   --  Input parameters:
  339.   --    pipename
  340.   --      Name of pipe from which to retrieve a message.  The message is 
  341.   --      copied into a local buffer which can be accessed by the 
  342.   --      "unpack_message" routine.  WARNING:  Do not use pipe names 
  343.   --      beginning with 'ORA$'.  These names are reserved for use by
  344.   --      procedures provided by Oracle Corporation. Pipename should not be
  345.   --      longer than 128 bytes, and is case-insensitive.
  346.   --    timeout
  347.   --      Time to wait for a message.  A timeout of 0 allows you to read 
  348.   --      without blocking.  
  349.   --  Return value:
  350.   --    0 - Success
  351.   --    1 - Timed out
  352.   --    2 - Record in pipe too big for buffer (should not happen).
  353.   --    3 - Interrupted
  354.   --
  355.   procedure reset_buffer;
  356.   --  Reset pack and unpack positioning indicators to 0.  Generally this
  357.   --    routine is not needed.
  358.   --
  359.   procedure purge(pipename in varchar2);
  360.   --  Empty out the named pipe.  An empty pipe is a candidate for LRU
  361.   --    removal from the SGA, therefore 'purge' can be used to free all
  362.   --    memory associated with a pipe.
  363.   --  Input Parameters:
  364.   --    pipename
  365.   --      Name of pipe from which to remove all messages.  The local 
  366.   --      buffer may be overwritten with messages as they are discarded.
  367.   --      Pipename should not be longer than 128 bytes, and is 
  368.   --      case-insensitive.
  369.   --
  370.   function unique_session_name return varchar2;
  371.   --  Get a name that is unique among all sessions currently connected
  372.   --    to this database.  Multiple calls to this routine from the same 
  373.   --    session will always return the same value.
  374.   --  Return value:
  375.   --    A unique name.  The returned name can be up to 30 bytes.
  376.   --
  377. end;
  378. /
  379.  
  380. drop public synonym dbms_pipe
  381. /
  382. create public synonym dbms_pipe for sys.dbms_pipe
  383. /
  384.  
  385.