//
//  Source File Name = cursor.sqC  
//  
//  Licensed Materials - Property of IBM 
//  
//  (C) COPYRIGHT International Business Machines Corp. 1995, 1997 
//  All Rights Reserved. 
//  
//  US Government Users Restricted Rights - Use, duplication or 
//  disclosure restricted by GSA ADP Schedule Contract with IBM Corp. 
//  
//  
//  PURPOSE: This sample program demonstrates the use of a CURSOR. 
//           The CURSOR is processed using static SQL.  This program 
//           obtains all managers in the STAFF table of the 
//           SAMPLE database and change their job from "Mgr" to 
//           "Clerk".  A ROLLBACK is done so that the SAMPLE 
//           database remains unchanged. 
//  
//  An external function "check_error" is contained in the file "util.C" 
//  which must be compiled along with this file. 
//  
//  EXTERNAL DEPENDENCIES : 
//        - Existing database for precompile purposes. 
//        - Precompile with the SQL precompiler (PREP in DB2) 
//        - Binding to a database (BIND in DB2) 
//        - Compiling and linking with the IBM Cset++ compiler (AIX and OS/2) 
//          or the Microsoft Visual C++ compiler (Windows) 
//          or the compiler supported on your platform. 
//  
//  For more information about these samples see the README file. 
//  
//  For more information on programming in C++, see the 
//     -  "Programming in C and C++" section of the Application Development Guide 
//  
//  For more information on building C++ applications, see the: 
//     - "Building C++ Applications" section of the Application Building Guide. 
//  
//  For more information on the SQL language see the SQL Reference. 

#include <iostream.h>
#include <stdlib.h>
#include <string.h>
#include "util.h"

EXEC SQL INCLUDE SQLCA;

#define  CHECKERR(CE_STR)   if (check_error (CE_STR, &sqlca) != 0)

class Cursor {
   public:
      Cursor ();
      Cursor (char *, char *);
      Fetch ();
      ~Cursor ();
   private:
      EXEC SQL BEGIN DECLARE SECTION;
         char   pname[10];
         short  dept;
         char userid[9];
         char passwd[19];
      EXEC SQL END DECLARE SECTION;
};


Cursor::Cursor () {
   cout << "Connect to default database with default userid and password.\n";
   EXEC SQL CONNECT TO sample;
   CHECKERR ("CONNECT TO") exit(1);
}


Cursor::Cursor (char *userid, char *passwd) {
   cout << "Connect to default database with inputted userid and password.\n";
   EXEC SQL CONNECT TO sample USER :userid USING :passwd;
   CHECKERR ("CONNECT TO sample") exit(1);
}


Cursor::Fetch () {
   EXEC SQL DECLARE c1 CURSOR FOR  /* :rk.1:erk. */
            SELECT name, dept FROM staff WHERE job='Mgr'
            FOR UPDATE OF job;
   CHECKERR ("DECLARE CURSOR") return 1;

   EXEC SQL OPEN c1;  /* :rk.2:erk. */
   CHECKERR ("OPEN CURSOR") return 1;

   do {
      EXEC SQL FETCH c1 INTO :pname, :dept;  /* :rk.3:erk. */
      if (SQLCODE != 0) break;

      cout << pname << " in dept. " << dept << " will be demoted to Clerk\n";
   } while ( 1 );

   EXEC SQL CLOSE c1;  /* :rk.4:erk. */
   CHECKERR ("CLOSE CURSOR") return 1;

   return 0;
}


Cursor::~Cursor () {
   EXEC SQL ROLLBACK;
   CHECKERR ("ROLLBACK") exit(1);
   cout << "\nOn second thought -- changes rolled back.\n";

   EXEC SQL CONNECT RESET;
   CHECKERR ("CONNECT RESET") exit(1);
}


int main(int argc, char *argv[]) {
   cout << "Sample C++ program: CURSOR \n";

   if (argc == 3) {
      Cursor sampleCursor (argv[1], argv[2]);
      sampleCursor.Fetch();
   } else if (argc == 1) {
      Cursor sampleCursor;
      sampleCursor.Fetch();
   } else {
      cout << "\nUSAGE: cursor userid passwd\n\n";
   } //  end if 

   return 0;
} //  end of program : cursor.sqC