home *** CD-ROM | disk | FTP | other *** search
/ Winzipper / Winzipper_ISO.iso / programming / oracle7 7.2 / OCI72 / CDEMO6.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1995-07-25  |  9.6 KB  |  369 lines

  1.  
  2. /* Copyright (c) 1991 by Oracle Corporation */
  3. /* 
  4.  *      -- cdemo6.cc --
  5.  *  An example program which illustrates how a C++ program
  6.  *  can use the OCI interface to access ORACLE database.
  7.  *
  8.  *  This program retrieves department name, given the
  9.  *  department number.
  10.  *  
  11.  *  The program queries the user for data as follows:
  12.  *   
  13.  *  Enter department number:
  14.  *   
  15.  *  The program terminates if -1 is entered
  16.  *  when the department number is requested.
  17.  */ 
  18. extern "C"
  19. {
  20. #include <stdio.h>
  21. #include <windows.h>
  22. #include <oratypes.h>
  23. #include <ociapr.h>
  24. /* demo constants and structs */
  25. #include <ocidem.h>
  26. extern "C"
  27. {
  28. #include <oratypes.h>
  29. #include <ocidfn.h>
  30. #include <ocidem.h>
  31. /* oparse flags */
  32. #define  DEFER_PARSE        1
  33. #define  NATIVE             1
  34. #define  VERSION_7          2 
  35. /* Class forward declarations */
  36. class connection;
  37. class cursor; 
  38. /*
  39.  * This class represents a connection to ORACLE database.
  40.  *
  41.  * NOTE: This connection class is just given as an example and 
  42.  * all possible operations on a connection have not been defined.
  43.  */
  44. class connection
  45. {
  46.   friend class cursor;
  47.   public:
  48.     connection() 
  49.       { state = not_connected;  
  50.         memset(&lda,0,sizeof(Lda_Def));
  51.         memset(&hda,0,HDA_SIZE); 
  52.       }
  53.     ~connection();
  54.     sword connect(const text *username, const text *password);
  55.     sword disconnect();
  56.     void display_error(FILE* file) const;
  57.   private:
  58.     Lda_Def lda;
  59.     ub1 hda[HDA_SIZE];
  60.     enum conn_state
  61.     {
  62.       not_connected,
  63.       connected
  64.     };
  65.     conn_state state;
  66. }; 
  67. /*
  68.  * This class represents an ORACLE cursor.
  69.  *
  70.  * NOTE: This cursor class is just given as an example and all
  71.  * possible operations on a cursor have not been defined.
  72.  */
  73. class cursor
  74. {
  75.   public:
  76.     cursor() 
  77.       {state = not_opened; conn = (connection *)0; }
  78.     ~cursor();
  79.     sword open(connection *conn_param);
  80.     sword close();
  81.     sword parse(const text *stmt)
  82.       { return (oparse(&cda, (text *)stmt, (sb4)-1, 
  83.                        DEFER_PARSE, (ub4) VERSION_7)); }
  84.     /* bind an input variable */
  85.     sword bind_by_position(sword sqlvnum, ub1 *progvar, 
  86.                            sword progvarlen, sword datatype, 
  87.                            sword scale, sb2 *indicator)
  88.       { return (obndrn(&cda, sqlvnum, progvar, progvarlen,
  89.                        datatype, scale, indicator, (text *)0, 
  90.                        -1, -1)); }
  91.     /* define an output variable */
  92.     sword define_by_position(sword position, ub1 *buf, 
  93.                              sword bufl, sword datatype, 
  94.                       
  95.       sword scale, sb2 *indicator, 
  96.                              ub2 *rlen, ub2 *rcode)
  97.       { return (odefin(&cda, position, buf, bufl, datatype, 
  98.                        scale, indicator,
  99.                        (text *)0, -1, -1, rlen, rcode)); }
  100.     sword describe(sword position, sb4 *dbsize, sb2 *dbtype, 
  101.                    sb1 *cbuf, sb4 *cbufl, sb4 *dsize, sb2 *prec,
  102.                    sb2 *scale, sb2 *nullok)
  103.       { return (odescr(&cda, position, dbsize, dbtype, 
  104.                        cbuf, cbufl, dsize,  prec, scale, nullok));
  105.       }
  106.     sword execute()
  107.       { return (oexec(&cda)); }
  108.     sword fetch()
  109.       { return (ofetch(&cda)); }
  110.     sword get_error_code() const
  111.       { return (cda.rc); }
  112.     void display_error( FILE* file) const;
  113.   private:
  114.     Cda_Def cda;
  115.     connection *conn;
  116.     enum cursor_state
  117.     {
  118.       not_opened,
  119.       opened
  120.     };
  121.     cursor_state state;
  122. }; 
  123. /*
  124.  * Error number macros
  125.  */
  126. #define CONERR_ALRCON -1            /* already connected */ 
  127. #define CONERR_NOTCON -2            /* not connected */ 
  128. #define CURERR_ALROPN -3            /* cursor is already open */
  129. #define CURERR_NOTOPN -4            /* cursor is not opened */
  130.  
  131.  
  132. /* exit status upon failure */
  133. #define  EXIT_FAILURE       1 
  134.  
  135. const text *username = (text *) "SCOTT";
  136. const text *password = (text *) "TIGER"; 
  137. /* define SQL statements to be used in the program */
  138. const text *seldept = (text *) "SELECT dname FROM dept WHERE deptno = :1"; 
  139. void err_report(FILE *file, text *errmsg, sword func_code);
  140. void myfflush(); 
  141. /* connection destructor */
  142. connection::~connection() 
  143. {
  144.   // disconnect if connection exists
  145.   if (state == connected)
  146.   {
  147.     if (disconnect())
  148.     {
  149.       display_error(stderr);
  150.     }
  151.   }
  152. /* connect to ORACLE */
  153. sword connection::connect(const text *username, const text *password)
  154. {
  155.   sword status; 
  156.   if (state == connected)
  157.   {
  158.     // this object is already connected
  159.     return (CONERR_ALRCON);
  160.   } 
  161.  
  162.   if ((status = olog(&lda, hda, (text *)username, -1,
  163.                      (text *)password, -1, (text *) 0, -1,
  164.                      OCI_LM_DEF)) == 0)
  165.   {
  166.     // successful login
  167.     state = connected;
  168.     printf("Connected to ORACLE as %s\n", username);
  169.   } 
  170.   return (status);
  171. /* disconnect from ORACLE */
  172. sword connection::disconnect()
  173. {
  174.   sword status; 
  175.   if (state == not_connected)
  176.   {
  177.     // this object has not been connected
  178.     return (CONERR_NOTCON);
  179.   } 
  180.   if ((status = ologof(&lda)) == 0)
  181.   {
  182.     // successful logout
  183.     state = not_connected;
  184.   } 
  185.   return (status);
  186. /* write error message to the given file */
  187. void connection::display_error(FILE *file) const
  188. {
  189.   if (lda.rc != 0)
  190.   {
  191.     sword n;
  192.     text msg[512]; 
  193.     n = oerhms((cda_def *)&lda, lda.rc, msg, (sword) sizeof(msg));
  194.     err_report(file, msg, lda.fc);
  195.   }
  196. /* cursor destructor */
  197. cursor::~cursor()
  198. {
  199.   if (state == opened)
  200.   {
  201.     if (close())
  202.       display_error(stderr);
  203.   }
  204. /* open the cursor */
  205. sword cursor::open(connection *conn_param)
  206. {
  207.   sword status; 
  208.   if (state == opened)
  209.   {
  210.     // this cursor has already been opened
  211.     return (CURERR_ALROPN);
  212.   } 
  213.   if ((status = oopen(&cda, &conn_param->lda, (text *)0, -1, -1, 
  214.                       (text *)0, -1)) == 0)
  215.   {
  216.     // successfull open
  217.     state = opened;
  218.     conn = conn_param;
  219.   } 
  220.   return (status);
  221. /* close the cursor */
  222. sword cursor::close()
  223. {
  224.   sword status; 
  225.   if (state == not_opened)
  226.   {
  227.     // this cursor has not been opened
  228.     return (CURERR_NOTOPN);
  229.   } 
  230.   if ((status = oclose(&cda)) == 0)
  231.   {
  232.     // successful cursor close
  233.     state = not_opened;
  234.     conn = (connection *)0;
  235.   } 
  236.   return (status);
  237. /* write error message to the given file */
  238. void cursor::display_error(FILE *file) const
  239. {
  240.   if (cda.rc != 0)
  241.   {
  242.     sword n;
  243.     text msg[512]; 
  244.     n = oerhms(&conn->lda, cda.rc, msg, (sword) sizeof(msg));
  245.     err_report(file, msg, cda.fc);
  246.   }
  247. int main()
  248. {
  249.     sword deptno;
  250.     sword len, dsize;
  251.     sb4   deptlen;
  252.     sb2   db_type;
  253.     sb1   name_buf[20];
  254.     text  *dept; 
  255. /* 
  256.  *  Connect to ORACLE and open a cursor.
  257.  *  Exit on any error.
  258.  */
  259.     connection conn;
  260.     if (conn.connect(username, password))
  261.     {
  262.       conn.display_error(stderr);
  263.       return(EXIT_FAILURE);
  264.     } 
  265.     cursor crsr;
  266.     if (crsr.open(&conn))
  267.     {
  268.       crsr.display_error(stderr);
  269.       return(EXIT_FAILURE);
  270.     } 
  271.     /* parse the SELDEPT statement */
  272.     if (crsr.parse(seldept))
  273.     {
  274.       crsr.display_error(stderr);
  275.       return(EXIT_FAILURE);
  276.     } 
  277.     /* bind the placeholder in the SELDEPT statement */
  278.     if (crsr.bind_by_position(1, (ub1 *) &deptno, 
  279.                               (sword) sizeof(deptno),
  280.                               INT_TYPE, -1, (sb2 *) 0))
  281.     {
  282.       crsr.display_error(stderr);
  283.       return(EXIT_FAILURE);
  284.     }   
  285.     /* describe the select-list field "dname" */
  286.     len = sizeof (name_buf);
  287.     if (crsr.describe(1, (sb4 *) &deptlen, &db_type,
  288.                       name_buf, (sb4 *) &len, (sb4 *) &dsize, 
  289.                      (sb2 *) 0, (sb2 *) 0, (sb2 *) 0))
  290.     {
  291.       crsr.display_error(stderr);
  292.       return(EXIT_FAILURE);
  293.     } 
  294.     /* allocate space for dept name now that you have length */
  295.     dept = new text((int) deptlen + 1); 
  296.     /* define the output variable for the select-list */
  297.     if (crsr.define_by_position(1, (ub1 *) dept, (sword)deptlen+1,
  298.                                 STRING_TYPE, -1, (sb2 *) 0, 
  299.                                (ub2 *) 0, (ub2 *) 0))
  300.     {
  301.       crsr.display_error(stderr);
  302.       delete dept;
  303.       return(EXIT_FAILURE);
  304.     } 
  305.     for (;;)
  306.     {
  307.         /* prompt for department number, */
  308.         /* break if given number == -1 */
  309.         printf("\nEnter department number (or -1 to EXIT): ");
  310.         while (scanf("%d", &deptno) != 1)
  311.         {
  312.           myfflush();
  313.           printf("Invalid input, please enter a number \
  314.                  (-1 to EXIT): ");
  315.         }
  316.         if (deptno == -1)
  317.         {
  318.           printf("Exiting... ");
  319.           break;
  320.         } 
  321.         /* display the name of the corresponding department */
  322.         if (crsr.execute() || crsr.fetch())
  323.         {
  324.           if (crsr.get_error_code() != NO_DATA_FOUND)
  325.           {
  326.             crsr.display_error(stderr);
  327.             delete dept;
  328.             return(EXIT_FAILURE);
  329.           }
  330.           else
  331.           printf("\n  The department number that you entered \
  332.                  doesn't exist.\n");
  333.         }
  334.         else
  335.        {
  336.        printf("\n  Department name = %s    \
  337.               Department number = %d\n", 
  338.               dept, deptno);
  339.        }
  340.     } 
  341.     delete dept;
  342.     printf ("\nG'day\n"); 
  343.   return 0;
  344. void err_report(FILE *file, text *errmsg, sword func_code)
  345. {
  346.     fprintf(file, "\n-- ORACLE error--\n\n%s\n", errmsg);
  347.     if (func_code > 0)
  348.         fprintf(file, "Processing OCI function %s\n",
  349.             oci_func_tab[func_code]);
  350. void myfflush()
  351. {
  352.   eb1 buf[50];
  353.  
  354.   fgets((char *) buf, 50, stdin);
  355. }
  356.   
  357.