home *** CD-ROM | disk | FTP | other *** search
/ Freelog 42 / Freelog042.iso / Alu / Ancestrologie / Sources / InterBase_WI-V6.0.1-server.ZIP / examples / api / api16.c < prev    next >
C/C++ Source or Header  |  2001-01-05  |  7KB  |  240 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.Inprise.com/IPL.html
  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 Inprise Corporation
  29.  * and its predecessors. Portions created by Inprise Corporation are
  30.  *
  31.  * Copyright (C) 2000 Inprise Corporation
  32.  * All Rights Reserved.
  33.  * Contributor(s): ______________________________________.
  34. */
  35. #include <stdlib.h>
  36. #include <string.h>
  37. #include <stdio.h>
  38. #include "example.h"
  39. #include <ibase.h>
  40.  
  41.  
  42. /*  Sleep for Windows is a stupid loop with I/O */
  43. #if defined  __BORLANDC__ || defined _MSC_VER
  44. #include <windows.h>
  45. #define SLEEP(x)    Sleep(x * 1000 )
  46. #else
  47. #define SLEEP(x)     sleep(x)
  48. #endif
  49.  
  50. short             event_flag = 0;
  51. isc_callback     ast_routine (char ISC_FAR *, short, char ISC_FAR *);
  52.  
  53. int main(ARG(int, argc), ARG(char **, argv))
  54. ARGLIST(int argc)
  55. ARGLIST(char **argv)
  56.  
  57. {
  58.     isc_db_handle    DB = NULL;      /* database handle */
  59.     isc_tr_handle     trans = NULL;     /* transaction handle */
  60.     isc_stmt_handle stmt = NULL;     /* transaction handle */
  61.     long        status[20];    /* status vector */
  62.     char ISC_FAR *    event_buffer; 
  63.     char ISC_FAR *    result_buffer;
  64.     long        event_id;
  65.     short        length;
  66.     char        dbname[128];
  67.     char        po_number[9];
  68.     XSQLDA ISC_FAR * sqlda;
  69.     short        nullind = 0;
  70.     char        query[128], update[128];
  71.     long        count[2], i = 0;
  72.     unsigned long    Vector[20];
  73.     char        ids[2][15];
  74.         int             first = 1;
  75.     int         ret = 0;
  76.     /* Transaction parameter block for read committed */
  77.     static char      isc_tpb[5] = {isc_tpb_version1,
  78.                       isc_tpb_write,
  79.                       isc_tpb_read_committed,
  80.                       isc_tpb_wait,
  81.                       isc_tpb_no_rec_version};
  82.     if (argc > 1)
  83.                 strcpy(dbname, argv[1]);
  84.         else
  85.         strcpy(dbname, "employee.gdb");
  86.  
  87.  
  88.     strcpy (ids[0], "new_order");
  89.     strcpy (ids[1], "change_order");
  90.     count[0] = 0;
  91.     count[1] = 0;
  92.  
  93.     sqlda = (XSQLDA ISC_FAR *) malloc(XSQLDA_LENGTH(1));
  94.     sqlda->sqln = 1;
  95.     sqlda->version = 1;
  96.     sqlda->sqlvar[0].sqldata = po_number;
  97.     sqlda->sqlvar[0].sqlind = &nullind;
  98.  
  99.     if (isc_attach_database (status, 0, dbname, &DB, 0, NULL))
  100.         {ERREXIT(status, 1)};
  101.  
  102.     /* SET TRANSACTION ISOLATION LEVEL READ COMMITTED */
  103.     if (isc_start_transaction (status, &trans, 1, &DB, 5, isc_tpb))
  104.         {ERREXIT(status, 1)};
  105.  
  106.     /* Prepare the query to look at the result tables */
  107.     strcpy(query, " SELECT po_number FROM sales \
  108.         WHERE order_status = 'new'  FOR UPDATE");
  109.  
  110.     /* This is for the update where current of */
  111.     strcpy(update, 
  112.         "UPDATE sales SET order_status = 'open' WHERE CURRENT OF C");
  113.     isc_dsql_allocate_statement(status, &DB, &stmt);
  114.  
  115.     if (isc_dsql_prepare(status, &trans, &stmt, 0, query, 1, sqlda))
  116.         {ERREXIT(status, 1)};
  117.  
  118.     /* Call the cursor "C" */
  119.     isc_dsql_set_cursor_name(status, &stmt, "C", 0);
  120.  
  121.     /* Allocate an event block and initialize its values 
  122.     **  This will wait on two named events 
  123.     */
  124.     length = (short)  isc_event_block((char ISC_FAR * ISC_FAR *) &event_buffer,
  125.                 (char ISC_FAR * ISC_FAR *) &result_buffer,
  126.  
  127.                  2, ids[0], ids[1], 0);
  128.  
  129.     /* Request the server to notify us of our events of interest.
  130.     ** When one of the two named events is triggered, the ast_routine
  131.     ** will be called with event_buffer, an updated buffer and length
  132.     ** que_events returns ast_returns value
  133.     */
  134.     if(isc_que_events(status, &DB, &event_id, length,
  135.              event_buffer, (isc_callback) ast_routine, result_buffer))
  136.         {ERREXIT(status, 1)};
  137.  
  138.  
  139.     while (!ret)
  140.     {
  141.  
  142.         i++;
  143.         /* If the event was triggered, reset the buffer and re-queue */
  144.         if (event_flag)
  145.         {
  146.  
  147.  
  148.                  /* Check for first ast_call.  isc_que_events fires
  149.                     each event to get processing started */
  150.  
  151.                   if ( first )
  152.                      {
  153.                       first = 0;
  154.                       event_flag = 0;
  155.                      }
  156.                   else
  157.                      {
  158.                     
  159.             event_flag = 0; 
  160.             /* event_counts will compare the various events 
  161.             ** listed in the two buffers and update the 
  162.             ** appropriate count_array elements with the difference
  163.             ** in the counts in the two buffers.
  164.             */
  165.  
  166.             isc_event_counts(Vector, length, (char ISC_FAR *) event_buffer,
  167.                 (char ISC_FAR *) result_buffer);
  168.  
  169.             /* Look through the count array */
  170.             count[0] += Vector[0];
  171.             count[1] += Vector[1];
  172.  
  173.             /* Select query to look at triggered events */
  174.             if (isc_dsql_execute(status, &trans, &stmt, 1, NULL))
  175.                 {ERREXIT(status, 1)};
  176.  
  177.             while (!isc_dsql_fetch(status, &stmt, 1, sqlda))
  178.             {
  179.                 po_number[8] = 0;
  180.                 printf("api16: %s\n", po_number);
  181.  
  182.                 /* exit on processing the last example record*/
  183.                 if (!strncmp(po_number, "VNEW4", 5))
  184.                     ret = 1;
  185.  
  186.                 /* Update current row */
  187.                 if(isc_dsql_execute_immediate(status, &DB, 
  188.                     &trans, 0, update, 1, NULL))
  189.                     {ERREXIT(status, 1)};
  190.             }
  191.             /* Close cursor */
  192.             isc_dsql_free_statement(status, &stmt, DSQL_close);
  193.  
  194.                     }
  195.  
  196.            /* Re-queue for the next event */
  197.  
  198.          if (isc_que_events(status, &DB, &event_id, length, 
  199.             event_buffer, (isc_callback) ast_routine, result_buffer))
  200.                  {ERREXIT(status, 1)};
  201.         }
  202.  
  203.         /* This does not block, but as a sample program there is nothing
  204.         ** else for us to do, so we will take a nap
  205.         */
  206.     SLEEP(1);
  207.     }
  208.     isc_commit_transaction(status, &trans);
  209.  
  210.     isc_detach_database (status, &DB);
  211.  
  212.     printf("Event complete, exiting\n");
  213.     free( sqlda);
  214.     return 0;
  215.  
  216. }
  217.  
  218. /*
  219. ** The called routine is always called with these three buffers.  Any
  220. ** event will land us here .  PLus we get called once when the 
  221. ** program first starts.
  222. */
  223. isc_callback ast_routine(ARG(char ISC_FAR *, result), 
  224.         ARG(short, length), 
  225.         ARG(char ISC_FAR *, updated))
  226. ARGLIST(char  *result)
  227. ARGLIST(char  *updated)
  228. ARGLIST(short length)
  229. {
  230.     /* Set the global event flag */
  231.  
  232.  
  233.     event_flag++;
  234.     printf("ast routine was called\n");
  235.     /* Copy the updated buffer to the result buffer */
  236.     while (length--)
  237.         *result++ = *updated++;
  238.     return 0;
  239. }
  240.