home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 January / Chip_2001-01_cd1.bin / tema / interb / InterBase_WI-V6.0-server.exe / server / examples / api / api16.c < prev    next >
C/C++ Source or Header  |  2000-06-23  |  7KB  |  243 lines

  1. /********************************************************************8
  2. **
  3. **    Program type:         API
  4. **
  5. **    Description:    This program does an asynchronous event wait
  6. **            on a trigger set up in employee.sales.  
  7. **            Somebody must add a new sales order to alert
  8. **            this program.  That role can be accomplished 
  9. **            by running programs stat12t or api16t at the
  10. **            same time.
  11. **    
  12. **            When the event is fired, this program selects
  13. **            back any new records and updates (current) those
  14. **            records to status "open".  The entire program runs
  15. **            in a single read-committed (wait, no version) 
  16. **            transaction, so transaction doesn't need to be started
  17. **            after an event.
  18.  * The contents of this file are subject to the Interbase Public
  19.  * License Version 1.0 (the "License"); you may not use this file
  20.  * except in compliance with the License. You may obtain a copy
  21.  * of the License at http://www.Interbase.com/IPL/
  22.  *
  23.  * Software distributed under the License is distributed on an
  24.  * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
  25.  * or implied. See the License for the specific language governing
  26.  * rights and limitations under the License.
  27.  *
  28.  * The Original Code was created by Interbase Software Corporation
  29.  * and its successors. Portions created by Borland/Inprise are
  30.  * Copyright (C) 1992-1998 and 1999-2000 Borland/Inprise. Portions
  31.  * created by InterBase Software Corporation are Copyright (C)
  32.  * 1998-1999 InterBase Software Corporation.
  33.  *
  34.  * Copyright (C) 2000 InterBase Software Corporation
  35.  * All Rights Reserved.
  36.  * Contributor(s): ______________________________________.
  37. */
  38. #include <stdlib.h>
  39. #include <string.h>
  40. #include <stdio.h>
  41. #include "example.h"
  42. #include <ibase.h>
  43.  
  44.  
  45. /*  Sleep for Windows is a stupid loop with I/O */
  46. #if defined  __BORLANDC__ || defined _MSC_VER
  47. #include <windows.h>
  48. #define SLEEP(x)    Sleep(x * 1000 )
  49. #else
  50. #define SLEEP(x)     sleep(x)
  51. #endif
  52.  
  53. short             event_flag = 0;
  54. isc_callback     ast_routine (char ISC_FAR *, short, char ISC_FAR *);
  55.  
  56. int main(ARG(int, argc), ARG(char **, argv))
  57. ARGLIST(int argc)
  58. ARGLIST(char **argv)
  59.  
  60. {
  61.     isc_db_handle    DB = NULL;      /* database handle */
  62.     isc_tr_handle     trans = NULL;     /* transaction handle */
  63.     isc_stmt_handle stmt = NULL;     /* transaction handle */
  64.     long        status[20];    /* status vector */
  65.     char ISC_FAR *    event_buffer; 
  66.     char ISC_FAR *    result_buffer;
  67.     long        event_id;
  68.     short        length;
  69.     char        dbname[128];
  70.     char        po_number[9];
  71.     XSQLDA ISC_FAR * sqlda;
  72.     short        nullind = 0;
  73.     char        query[128], update[128];
  74.     long        count[2], i = 0;
  75.     unsigned long    Vector[20];
  76.     char        ids[2][15];
  77.         int             first = 1;
  78.     int         ret = 0;
  79.     /* Transaction parameter block for read committed */
  80.     static char      isc_tpb[5] = {isc_tpb_version1,
  81.                       isc_tpb_write,
  82.                       isc_tpb_read_committed,
  83.                       isc_tpb_wait,
  84.                       isc_tpb_no_rec_version};
  85.     if (argc > 1)
  86.                 strcpy(dbname, argv[1]);
  87.         else
  88.         strcpy(dbname, "employee.gdb");
  89.  
  90.  
  91.     strcpy (ids[0], "new_order");
  92.     strcpy (ids[1], "change_order");
  93.     count[0] = 0;
  94.     count[1] = 0;
  95.  
  96.     sqlda = (XSQLDA ISC_FAR *) malloc(XSQLDA_LENGTH(1));
  97.     sqlda->sqln = 1;
  98.     sqlda->version = 1;
  99.     sqlda->sqlvar[0].sqldata = po_number;
  100.     sqlda->sqlvar[0].sqlind = &nullind;
  101.  
  102.     if (isc_attach_database (status, 0, dbname, &DB, 0, NULL))
  103.         {ERREXIT(status, 1)};
  104.  
  105.     /* SET TRANSACTION ISOLATION LEVEL READ COMMITTED */
  106.     if (isc_start_transaction (status, &trans, 1, &DB, 5, isc_tpb))
  107.         {ERREXIT(status, 1)};
  108.  
  109.     /* Prepare the query to look at the result tables */
  110.     strcpy(query, " SELECT po_number FROM sales \
  111.         WHERE order_status = 'new'  FOR UPDATE");
  112.  
  113.     /* This is for the update where current of */
  114.     strcpy(update, 
  115.         "UPDATE sales SET order_status = 'open' WHERE CURRENT OF C");
  116.     isc_dsql_allocate_statement(status, &DB, &stmt);
  117.  
  118.     if (isc_dsql_prepare(status, &trans, &stmt, 0, query, 1, sqlda))
  119.         {ERREXIT(status, 1)};
  120.  
  121.     /* Call the cursor "C" */
  122.     isc_dsql_set_cursor_name(status, &stmt, "C", 0);
  123.  
  124.     /* Allocate an event block and initialize its values 
  125.     **  This will wait on two named events 
  126.     */
  127.     length = (short)  isc_event_block((char ISC_FAR * ISC_FAR *) &event_buffer,
  128.                 (char ISC_FAR * ISC_FAR *) &result_buffer,
  129.  
  130.                  2, ids[0], ids[1], 0);
  131.  
  132.     /* Request the server to notify us of our events of interest.
  133.     ** When one of the two named events is triggered, the ast_routine
  134.     ** will be called with event_buffer, an updated buffer and length
  135.     ** que_events returns ast_returns value
  136.     */
  137.     if(isc_que_events(status, &DB, &event_id, length,
  138.              event_buffer, (isc_callback) ast_routine, result_buffer))
  139.         {ERREXIT(status, 1)};
  140.  
  141.  
  142.     while (!ret)
  143.     {
  144.  
  145.         i++;
  146.         /* If the event was triggered, reset the buffer and re-queue */
  147.         if (event_flag)
  148.         {
  149.  
  150.  
  151.                  /* Check for first ast_call.  isc_que_events fires
  152.                     each event to get processing started */
  153.  
  154.                   if ( first )
  155.                      {
  156.                       first = 0;
  157.                       event_flag = 0;
  158.                      }
  159.                   else
  160.                      {
  161.                     
  162.             event_flag = 0; 
  163.             /* event_counts will compare the various events 
  164.             ** listed in the two buffers and update the 
  165.             ** appropriate count_array elements with the difference
  166.             ** in the counts in the two buffers.
  167.             */
  168.  
  169.             isc_event_counts(Vector, length, (char ISC_FAR *) event_buffer,
  170.                 (char ISC_FAR *) result_buffer);
  171.  
  172.             /* Look through the count array */
  173.             count[0] += Vector[0];
  174.             count[1] += Vector[1];
  175.  
  176.             /* Select query to look at triggered events */
  177.             if (isc_dsql_execute(status, &trans, &stmt, 1, NULL))
  178.                 {ERREXIT(status, 1)};
  179.  
  180.             while (!isc_dsql_fetch(status, &stmt, 1, sqlda))
  181.             {
  182.                 po_number[8] = 0;
  183.                 printf("api16: %s\n", po_number);
  184.  
  185.                 /* exit on processing the last example record*/
  186.                 if (!strncmp(po_number, "VNEW4", 5))
  187.                     ret = 1;
  188.  
  189.                 /* Update current row */
  190.                 if(isc_dsql_execute_immediate(status, &DB, 
  191.                     &trans, 0, update, 1, NULL))
  192.                     {ERREXIT(status, 1)};
  193.             }
  194.             /* Close cursor */
  195.             isc_dsql_free_statement(status, &stmt, DSQL_close);
  196.  
  197.                     }
  198.  
  199.            /* Re-queue for the next event */
  200.  
  201.          if (isc_que_events(status, &DB, &event_id, length, 
  202.             event_buffer, (isc_callback) ast_routine, result_buffer))
  203.                  {ERREXIT(status, 1)};
  204.         }
  205.  
  206.         /* This does not block, but as a sample program there is nothing
  207.         ** else for us to do, so we will take a nap
  208.         */
  209.     SLEEP(1);
  210.     }
  211.     isc_commit_transaction(status, &trans);
  212.  
  213.     isc_detach_database (status, &DB);
  214.  
  215.     printf("Event complete, exiting\n");
  216.     free( sqlda);
  217.     return 0;
  218.  
  219. }
  220.  
  221. /*
  222. ** The called routine is always called with these three buffers.  Any
  223. ** event will land us here .  PLus we get called once when the 
  224. ** program first starts.
  225. */
  226. isc_callback ast_routine(ARG(char ISC_FAR *, result), 
  227.         ARG(short, length), 
  228.         ARG(char ISC_FAR *, updated))
  229. ARGLIST(char  *result)
  230. ARGLIST(char  *updated)
  231. ARGLIST(short length)
  232. {
  233.     /* Set the global event flag */
  234.  
  235.  
  236.     event_flag++;
  237.     printf("ast routine was called\n");
  238.     /* Copy the updated buffer to the result buffer */
  239.     while (length--)
  240.         *result++ = *updated++;
  241.     return 0;
  242. }
  243.