home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / dbutil.zip / BUFOP.ZIP / HOSTVARS.CPP < prev    next >
Text File  |  1993-11-01  |  11KB  |  375 lines

  1. // Precompiler support files
  2. #include "compsql.hpp"
  3. #include "pctypes.hpp"       // precompiler types
  4. #include "hostvars.hpp"
  5. #include <fstream.h>
  6. #include <IEqseq.h>
  7. #include <Ikeyset.h>
  8. #include <iglobals.h>
  9.  
  10. typedef IEqualitySequence <Variable> VarListType;      // collection of variables
  11. typedef IKeySet<Vtype,IString>  ValidSQLTypes; // collection of sql types
  12.  
  13. VarListType VarList;
  14. ValidSQLTypes ValidTypes;
  15.  
  16.  
  17.  
  18. extern sqlca  mysqlca;
  19. extern ofstream monitor;     // monitor output file name from compsql.h
  20.  
  21. static Boolean InDeclareSection;
  22. Boolean InDeclare()
  23. { return InDeclareSection;}
  24.  
  25. void setDeclare(Boolean B)
  26. { InDeclareSection = B;}
  27.  
  28.  
  29.  
  30.   VarListType::Cursor VarCursor(VarList);   //used to locate by name
  31.  
  32.  
  33.  
  34.  
  35.  
  36. /********************************************************************** 
  37. *  Variable class implementation
  38. *    this is made into a class to store the information into a
  39. *    sequence container for SQL Processing
  40. *
  41. **********************************************************************/
  42. unsigned long Variable::nxtID=0;
  43. Variable:: Variable(){
  44.  
  45.     name = "";
  46.     type = 0;
  47.     len = 0;
  48.     Obj = false;
  49.     aPointer = false;
  50.     ID = 0;}
  51.  
  52. Variable:: Variable(IString & theName, int thelen, int theType, Boolean anObj)
  53.     {   name = theName;
  54.         len = thelen;
  55.         type = theType;
  56.         Obj = anObj;
  57.         aPointer = false;
  58.         ID = 0;
  59. //      setID();
  60.     }
  61.  
  62.  
  63. ostream& operator<<(ostream & os, Variable & V)
  64. {
  65.    os << "Name: " << V.name << "  Len: " << V.len
  66.       << "  Type: " << V.type << " " << V.vTypeTxt << " ID: " << V.ID << "\n";
  67.    return os;
  68. }
  69.  
  70. void Variable::setName(const IString & thename)
  71.  {
  72.     name = thename;
  73.  
  74.     name.strip(' ');
  75.     name.strip(';');
  76.  }
  77.  
  78.  
  79. void Variable::registerHV()        // register the hostvar
  80. {
  81.    setID();                        // assign an ID
  82.    unsigned short namelen = name.length();
  83.    unsigned short location;
  84.    if (InDeclare()) {
  85.        location = SQLA_DECLARE_SECT;
  86.        int rc = sqlaahvr(&namelen,name,&type,&len,&ID,
  87.                          &location,NULL,&mysqlca);
  88.    } else {
  89.        location = SQLA_SQL_STMT;
  90.        int rc = sqlaahvr(&namelen,name,&type,&len,&ID,
  91.                          &location,NULL,&mysqlca);
  92.  
  93.    } /* endif */
  94.    if (! mysqlca.sqlcode==0 ) {
  95.       MSQLError(ID);
  96.    } /* endif */
  97.  }
  98.  
  99. Variable & Variable::operator=(Variable const & v)
  100.   { if (this == & v)
  101.       return *this;
  102.      name = v.name;
  103.      len = v.len;
  104.      type = v.type;
  105.      ID = v.ID;
  106.      aPointer = v.aPointer;
  107.      prefix = v.prefix;
  108.      }
  109.  
  110. Variable:: Variable(IString & theName)
  111.     {   name = theName;
  112.         len = 0;
  113.         type = 0;
  114.         Obj = false;
  115.         aPointer = false;
  116.         ID = 0;
  117.     }
  118.  
  119. void Variable::setDefaults(Vtype const & V )
  120.  
  121. {   
  122.    len = V.getLen();
  123.    type = V.getType();
  124.    vTypeTxt = V.getName();
  125.    IsObject = V.isObj();
  126.     aPointer = false;
  127. }
  128.  
  129. void Variable::setV(unsigned short sqlaID, unsigned short idx,ofstream & fout)
  130. /************************************ 
  131. *  Generate a call to SETV in the form
  132. *  sqlsetv(sqlaid,idx,type,len,&name,NULL,NULL);
  133. **************************************/
  134. {  int tmplen = len;
  135.    if ((type == SQL_TYP_CHAR) && len > 1) {
  136.       tmplen--;
  137.    } /* endif */
  138.    fout << "      sqlasetv(" 
  139.         << sqlaID   << "," 
  140.         << idx      << " ,"
  141.         << type     << ","
  142.         << len      << ","
  143.         << getFullName()
  144.         << ",NULL,NULL); // set host variable with no null indicator \n";
  145. }
  146.  
  147. void Variable:: setVNull(unsigned short sqlaID, unsigned short idx,ofstream & fout,
  148.                          int nullID)
  149. /************************************
  150. *  Generate a call to SETV in the form
  151. *  sqlsetv(sqlaid,idx,type+1,len,&name,&nullInd,NULL);
  152. **************************************/
  153. {
  154.    Variable V;
  155.    V = getVarByID(nullID);
  156.  
  157.    fout << "      sqlasetv(" 
  158.         << sqlaID   << ","
  159.         << idx      << " ,"
  160.         << type+1   << ","
  161.         << len      << ","
  162.         << getFullName() << ","
  163.         << V.getFullName() 
  164.         << ",NULL); // set host variable with a null indicator \n";
  165.  
  166.  
  167. }
  168.  
  169.  
  170. IString Variable:: getFullName()
  171. /***********************************************************
  172. *  return prefix and name  for use in setV
  173. *  if the variable is not an address (isAddress = false)
  174. *  then prefix the name with the "&"
  175. **************************************************************/
  176. {
  177.    IString tmp = prefix+name;
  178.    if (!aPointer)
  179.      tmp.insert("&");
  180.    return tmp;
  181. }
  182.  
  183.  
  184.  
  185. void Variable:: setUnknown()
  186.  {
  187.     len = 0;
  188.     type = 0;
  189.     vTypeTxt = "Unknown variable - should be SQLDA";
  190.     IsObject = false;
  191.     aPointer = false;
  192. }
  193.   
  194. Variable:: ~Variable(){}
  195.  
  196.  
  197.  
  198. void initSQLTypes(){
  199. /*********************************************************************
  200. *  Took some liberties here in defining sql types.
  201. *  In support of IString, I defined a new type which is derived from
  202. *  IString.
  203. *
  204. *  each of the types are defined and added to the keyset
  205. *
  206. *   N O T E   I do not support structures in this implementation
  207. *       planned for release 2  ha ha!
  208. **********************************************************************/
  209.   initSQLStuff();
  210.  
  211.    Vtype aVtype;
  212.  
  213.     aVtype.setParams("fchar",SQL_TYP_CHAR,1);       // fixed char
  214.     ValidTypes.add(aVtype);
  215.  
  216.     aVtype.setParams("char",SQL_TYP_CSTR,1);        // var length null term
  217.     ValidTypes.add(aVtype);
  218.  
  219.     aVtype.setParams("ZString",SQL_TYP_CHAR,1,true);// IString, with length (C++ tools)
  220.     ValidTypes.add(aVtype);
  221.  
  222.     aVtype.setParams("NString",SQL_TYP_CHAR,1);// same as Istring but null term
  223.     ValidTypes.add(aVtype);
  224.  
  225.     aVtype.setParams("IDate",SQL_TYP_DATE,SQL_DATE_STRLEN,true);  // IDate from C++ Tools
  226.     ValidTypes.add(aVtype);
  227.  
  228.     aVtype.setParams("ITime",SQL_TYP_TIME,SQL_TIME_STRLEN,true);// same as Istring but null term
  229.     ValidTypes.add(aVtype);
  230.  
  231.     aVtype.setParams("float",SQL_TYP_FLOAT,SQL_FLOAT_LENGTH);       // 8-byte floating point IEEE
  232.     ValidTypes.add(aVtype);
  233.  
  234.     aVtype.setParams("int",SQL_TYP_INTEGER,SQL_INT_LENGTH);         // long int (4 byte)
  235.     ValidTypes.add(aVtype);
  236.  
  237.     aVtype.setParams("short",SQL_TYP_SMALL,SQL_SMALL_LENGTH);       // short int 16 bit
  238.     ValidTypes.add(aVtype);
  239.  
  240.     aVtype.setParams("Boolean",SQL_TYP_CHAR,1);       // translate to "T" or "F"
  241.     ValidTypes.add(aVtype);            // on the database
  242.  
  243.    return;
  244. }
  245.     
  246.  
  247. void processDeclare(IString & theStr)
  248. /**************************************************************************** 
  249. *   P R O C E S S   D E C L A R E
  250. *  This routine is entered with a string from the source program and is
  251. *  evaluated for a valid variable.  If one is found it is added to the
  252. *  variable list
  253. *
  254. * N O T E - 
  255. *   for the host variables I'm not sure what type of collection structure 
  256. *   to use I have a collection that must be accessed by two different methods.
  257. *   The name (which I defined as a key)
  258. *   and an integer ID (defined as a sequence number). 
  259. *   the host program refers to the variable by name, while the precompiler
  260. *   services uses the variable ID.   I chose the sequence
  261. *   because while the order of entry is not important, once a variable is 
  262. *   added, I use its position as the precompiler services ID.
  263. ****************************************************************************/
  264. {Vtype theType;
  265.  
  266.     if (theStr.length() == 0) {
  267.        return;
  268.     } /* endif */
  269.     if (theStr.includes("const")) {              // no can do
  270.        return;
  271.     } /* endif */
  272.     theStr.change("unsigned","");          // these words have not meaning in the database types
  273.     theStr.change("signed","");
  274.     theStr = theStr.change("short int","short"); // get rid of long / short qualifiers
  275.     theStr = theStr.change("long int","int");
  276.     theStr = theStr.change("double","float");    // DB2 will use auto converting
  277.     if (theStr.numWords() == 1) {
  278.        theStr.insert("int ");
  279.     } /* endif */
  280.     IString theSType = theStr.word(1);           // get first word for possible type
  281. //    ValidSQLTypes::Cursor c(ValidTypes);         // create cursor for valid types
  282. //    Vtype x;
  283.     if (ValidTypes.containsElementWithKey(theSType)) {
  284.                                                 // have a valid SQL type
  285.                                                 // parse the rest of the stament
  286.         theType=ValidTypes.elementWithKey(theSType);  // get the type
  287.         
  288.         Variable myVar;                         // put here - so it doesn't get init
  289.         myVar.setDefaults(theType);            // unless needed
  290.         if (theStr.includes("*")) {
  291.            myVar.setPointer();
  292.            theStr = theStr.remove("*",1);
  293.         } /* endif */
  294.         if (theStr.includes("[")) {              // has associated length
  295.            int start = theStr.indexOf('[');     // get the length
  296.            int end   = theStr.indexOf(']');     // what's between should be length
  297.            IString tmp = theStr.subString(start+1,end-start-1);
  298.            myVar.setLen(tmp.asUnsigned());
  299.  
  300.            theStr.remove(start,end);
  301.         } /* endif */
  302.  
  303.         myVar.setName(theStr.word(2));
  304.         myVar.registerHV();                    // register the hostvar
  305.  
  306.         VarList.add(myVar);                  // add to host variable list
  307.     } else {                                // not a host variable
  308.        return;
  309.     } /* endif */
  310. }  // end process declare
  311.  
  312.  
  313. /*********************************************************************** 
  314. * FUNCTION  GetVarByName
  315. *   Host variables are stored in the sequence collection - VarList
  316. *       Pass the variable name
  317. *       return the variable
  318. *       If the variable is not found, assume it is a dynamic SQLDA or
  319. *                   A nul indicator
  320. ************************************************************************/
  321.  
  322.  
  323.  
  324. Variable *  getVarByName(IString const& theName)
  325.   { Variable  aVar;
  326.     aVar.setName(theName);
  327.     VarCursor.setToFirst();
  328.     if (VarList.locate(aVar,VarCursor))
  329.          return &VarList.elementAt(VarCursor);  // item was found return it
  330.      aVar.setUnknown();                              // don't know but keep it
  331.      aVar.registerHV();
  332.      VarList.add(aVar);
  333.      VarCursor.invalidate();
  334.      VarCursor.setToLast();
  335.      return &VarList.elementAt(VarCursor);
  336.     } 
  337.  
  338. // given an ID, get the variable
  339. Variable & getVarByID(long theID)
  340.  { Boolean B;
  341.    VarCursor.setToFirst();
  342.    for (int j=1;j<theID ;j++) {
  343.       VarCursor.setToNext();
  344.    } /* endfor */
  345.    if (VarCursor.isValid()) {
  346.       return VarList.elementAt(VarCursor);
  347.    } else {
  348.       monitor << "Internal error in program; Variable ID " 
  349.               << theID 
  350.               << "Does not exist \n";
  351.       dumpVars();
  352.       monitor.flush();
  353.       Variable aVar;
  354.       aVar.changeID(theID);
  355.       aVar.setName("Unknown - error");
  356.       VarList.add(aVar);
  357.       VarCursor.setToLast();
  358.    } /* endif */
  359.   return VarList.elementAt(VarCursor);
  360.  }
  361.   
  362.  
  363. void dumpVars()
  364.  
  365. {
  366.    Variable AVar;
  367.  
  368.    VarCursor.setToFirst();
  369.    monitor << "All registered host variables \n ";
  370.    forCursor(VarCursor)
  371.     {
  372.       monitor << VarList.elementAt(VarCursor);
  373.    } 
  374.  }
  375.