Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

rdbModel::MysqlConnection Class Reference

#include <MysqlConnection.h>

Inheritance diagram for rdbModel::MysqlConnection:

rdbModel::Connection rdbModel::Visitor rdbModel::Connection rdbModel::Visitor List of all members.

Public Types

enum  VisitorState {
  VCONTINUE = 0, VDONE, VBRANCHDONE, VERROR,
  VERRORABORT
}
enum  VisitorState {
  VCONTINUE = 0, VDONE, VBRANCHDONE, VERROR,
  VERRORABORT
}

Public Member Functions

virtual bool close ()
virtual bool close ()
virtual bool compileAssertion (const Assertion *a, std::string &sqlString) const
virtual bool compileAssertion (const Assertion *a, std::string &sqlString) const
virtual ResultHandledbRequest (const std::string &request)
virtual ResultHandledbRequest (const std::string &request)
virtual void disableModify (bool disable)
virtual void disableModify (bool disable)
std::ostreamgetErrOut () const
std::ostreamgetErrOut () const
std::ostreamgetOut () const
std::ostreamgetOut () const
virtual bool insertRow (const std::string &tableName, const StringVector &colNames, const StringVector &values, int *auto_value=0, const StringVector *nullCols=0)
virtual bool insertRow (const std::string &tableName, const StringVector &colNames, const StringVector &values, int *auto_value=0, const StringVector *nullCols=0)
virtual bool isConnected ()
 Return true iff open has been done with no matching close.
virtual bool isConnected ()
 Return true iff open has been done with no matching close.
virtual MATCH matchSchema (Rdb *rdb, bool matchDbName=true)
virtual MATCH matchSchema (Rdb *rdb, bool matchDbName=true)
 MysqlConnection (std::ostream *out=0, std::ostream *errOut=0)
 MysqlConnection (std::ostream *out=0, std::ostream *errOut=0)
virtual bool open (const std::string &parms)
virtual bool open (const std::string &host, const std::string &userid, const std::string &password, const std::string &dbName)
virtual bool open (const std::string &parms)
virtual bool open (const std::string &host, const std::string &userid, const std::string &password, const std::string &dbName)
virtual ResultHandleselect (const std::string &tableName, const StringVector &getCols, const StringVector &orderCols, const Assertion *where=0, int rowLimit=0, int rowOffset=0)
virtual ResultHandleselect (const std::string &tableName, const StringVector &getCols, const StringVector &orderCols, const Assertion *where=0, int rowLimit=0, int rowOffset=0)
virtual unsigned int update (const std::string &tableName, const StringVector &colNames, const StringVector &values, const Assertion *where=0, const StringVector *nullCols=0)
virtual unsigned int update (const std::string &tableName, const StringVector &colNames, const StringVector &values, const Assertion *where=0, const StringVector *nullCols=0)
virtual Visitor::VisitorState visitAssertion (Assertion *)
virtual Visitor::VisitorState visitAssertion (Assertion *)
virtual Visitor::VisitorState visitColumn (Column *)
virtual Visitor::VisitorState visitColumn (Column *)
virtual Visitor::VisitorState visitIndex (Index *)
virtual Visitor::VisitorState visitIndex (Index *)
virtual VisitorState visitInsertNew (InsertNew *)
virtual VisitorState visitInsertNew (InsertNew *)
virtual VisitorState visitInterRow (InterRow *)
virtual VisitorState visitInterRow (InterRow *)
virtual VisitorState visitQuery (Query *)
virtual VisitorState visitQuery (Query *)
virtual Visitor::VisitorState visitRdb (Rdb *)
 This method sets if the visitor is recursive or not.
virtual Visitor::VisitorState visitRdb (Rdb *)
 This method sets if the visitor is recursive or not.
virtual VisitorState visitSet (Set *)
virtual VisitorState visitSet (Set *)
virtual VisitorState visitSupersede (Supersede *)
virtual VisitorState visitSupersede (Supersede *)
virtual Visitor::VisitorState visitTable (Table *)
virtual Visitor::VisitorState visitTable (Table *)
virtual ~MysqlConnection ()
virtual ~MysqlConnection ()

Private Types

enum  VISITOR { VISITORundefined, VISITORmatch }
enum  VISITOR { VISITORundefined, VISITORmatch }

Private Member Functions

bool checkDType (Datatype *dtype, const std::string &sqlType)
bool checkDType (Datatype *dtype, const std::string &sqlType)

Static Private Member Functions

bool compileComparison (Assertion::Operator *op, std::string &sqlString)
bool compileComparison (Assertion::Operator *op, std::string &sqlString)
void compileInit ()
void compileInit ()
bool compileOperator (Assertion::Operator *op, std::string &sqlString)
bool compileOperator (Assertion::Operator *op, std::string &sqlString)

Private Attributes

std::map< std::string, unsigned
int > 
m_colIx
 Index by colname; data is row number with "SHOW COLUMNS.." result set.
std::map< std::string, unsigned
int > 
m_colIx
 Index by colname; data is row number with "SHOW COLUMNS.." result set.
bool m_connected
std::string m_dbName
std::ostreamm_err
std::ostreamm_err
std::string m_host
bool m_matchDbName
MATCH m_matchReturn
 Keep track of status during matching process.
MYSQLm_mysql
MYSQLm_mysql
std::vector< Column * > m_ourCols
std::vector< Column * > m_ourCols
std::ostreamm_out
std::ostreamm_out
std::string m_password
std::string m_primColName
Rdbm_rdb
 If successful match, save pointer to schema for use with smart insert.
Rdbm_rdb
 If successful match, save pointer to schema for use with smart insert.
MYSQL_RESm_tempRes
 For query results while visiting.
MYSQL_RESm_tempRes
 For query results while visiting.
std::string m_user
VISITOR m_visitorType
bool m_writeDisabled

Static Private Attributes

bool m_compileInit = false

Detailed Description

Class to handle connection to a MySQL database

Initial design will just use host, password, userid passed in. Will be up to caller to insure that the userid has the right privilages for the operations caller intends to do.


Member Enumeration Documentation

enum rdbModel::MysqlConnection::VISITOR [private]
 

Someday we may want more than one kind of visitor; for example, might want one to create dbs

Enumeration values:
VISITORundefined 
VISITORmatch 
00158                  {
00159       VISITORundefined,
00160       VISITORmatch
00161     };

enum rdbModel::MysqlConnection::VISITOR [private]
 

Someday we may want more than one kind of visitor; for example, might want one to create dbs

Enumeration values:
VISITORundefined 
VISITORmatch 
00158                  {
00159       VISITORundefined,
00160       VISITORmatch
00161     };

enum rdbModel::Visitor::VisitorState [inherited]
 

Enumeration values:
VCONTINUE 
VDONE 
VBRANCHDONE 
VERROR 
VERRORABORT 
00034                        {
00035       VCONTINUE = 0,
00036       VDONE,         // visitor has had its fill of visiting
00037       VBRANCHDONE,   // don't descend further; go to next sibling, if any
00038       VERROR,        // error during visit; perhaps can continue, though
00039       VERRORABORT    // error during visit; can't handle more
00040     };

enum rdbModel::Visitor::VisitorState [inherited]
 

Enumeration values:
VCONTINUE 
VDONE 
VBRANCHDONE 
VERROR 
VERRORABORT 
00034                        {
00035       VCONTINUE = 0,
00036       VDONE,         // visitor has had its fill of visiting
00037       VBRANCHDONE,   // don't descend further; go to next sibling, if any
00038       VERROR,        // error during visit; perhaps can continue, though
00039       VERRORABORT    // error during visit; can't handle more
00040     };


Constructor & Destructor Documentation

rdbModel::MysqlConnection::MysqlConnection std::ostream out = 0,
std::ostream errOut = 0
 

Open a connection Allowed operations will depend on userid, etc., specified return true if successful

00070                                                        :
00071     m_mysql(0), m_connected(0), m_out(out), m_err(errOut),
00072     m_visitorType(VISITORundefined), m_rdb(0), m_tempRes(0),
00073     m_writeDisabled(false)                                   {
00074     if (m_out == 0) m_out = &std::cout;
00075     if (m_err == 0) m_err = &std::cerr;
00076   }

rdbModel::MysqlConnection::~MysqlConnection  )  [virtual]
 

00090                                     {
00091     close();
00092     delete m_mysql;
00093     return;
00094   }

rdbModel::MysqlConnection::MysqlConnection std::ostream out = 0,
std::ostream errOut = 0
 

Open a connection Allowed operations will depend on userid, etc., specified return true if successful

virtual rdbModel::MysqlConnection::~MysqlConnection  )  [virtual]
 


Member Function Documentation

bool rdbModel::MysqlConnection::checkDType Datatype dtype,
const std::string &  sqlType
[private]
 

bool rdbModel::MysqlConnection::checkDType Datatype dtype,
const std::string &  sqlType
[private]
 

00729                                 {
00730     std::string base;
00731     int sqlSize;
00732     if (dtype->getType() != Datatype::TYPEenum) {
00733       sqlSize = extractSize(sqlType);
00734     }
00735 
00736     // Cases  char, varchar, enum and datetime are handled entirely within
00737     // the switch statement, but most do the bulk of the work in
00738     // common, after the switch.
00739     switch (dtype->getType()) {
00740       case Datatype::TYPEenum: {
00741                                  base = "enum";
00742                                  if (sqlType.find(base) != 0) {
00743                                    m_matchReturn = MATCHfail;
00744                                    return false;
00745                                  }
00746                                  Enum* ourEnum = dtype->getEnum();
00747                                  // Finally compare local list of choices to those listed in sqlType
00748                                  // Local list is a vector; in sqlType they're quoted, comma separated
00749                                  return compareEnumList(ourEnum->getChoices(), sqlType);
00750                                }
00751       case Datatype::TYPEvarchar: {
00752                                     base = "varchar";
00753                                     if (sqlType.find(base) != 0) {
00754                                       m_matchReturn = MATCHfail;
00755                                       return false;
00756                                     }
00757                                     // size in db must be at least as large as size in Col.
00758                                     if (sqlSize < dtype->getOutputSize()) {
00759                                       m_matchReturn = MATCHfail;
00760                                       return false;
00761                                     }
00762                                     else if (sqlSize > dtype->getOutputSize()) {
00763                                       m_matchReturn = MATCHcompatible;
00764                                     }
00765                                     return true;
00766                                   }
00767       case Datatype::TYPEchar: {
00768                                  base = "char";
00769                                  if (sqlType.find(base) != 0) {
00770                                    m_matchReturn = MATCHfail;
00771                                    return false;
00772                                  }
00773                                  //  For char datatype unspecified size is equivalent to size=1
00774                                  if (!sqlSize) sqlSize = 1;
00775                                  // size in db must be at least as large as size in Col.
00776                                  if (sqlSize < dtype->getOutputSize()) {
00777                                    m_matchReturn = MATCHfail;
00778                                    return false;
00779                                  }
00780                                  else if (sqlSize > dtype->getOutputSize()) {
00781                                    m_matchReturn = MATCHcompatible;
00782                                  }
00783                                  return true;
00784                                }
00785       case Datatype::TYPEdatetime: {
00786                                      if (sqlType != "datetime") {
00787                                        m_matchReturn = MATCHfail;
00788                                        return false;
00789                                      }
00790                                      return true;
00791                                    }
00792 
00793 
00794       case Datatype::TYPEtimestamp: {
00795                                       base = "timestamp";
00796                                       break;
00797                                     }
00798       case Datatype::TYPEint: {
00799                                 base = "int";
00800                                 break;
00801                               }
00802       case Datatype::TYPEmediumint: {
00803                                       base = "mediumint";
00804                                       break;
00805                                     }
00806       case Datatype::TYPEsmallint: {
00807                                      base = "smallint";
00808                                      break;
00809                                    }
00810       case Datatype::TYPEreal: 
00811       case Datatype::TYPEdouble: {
00812                                    base = "double";
00813                                    break;
00814                                  }
00815       default: {  // Indicates bad xml file input.  Applications
00816                  //should have exited already
00817                  m_matchReturn = MATCHfail;
00818                  return false;
00819                }
00820     }     // end switch
00821     if (sqlType.find(base) != 0) {
00822       m_matchReturn = MATCHfail;
00823       return false;
00824     }
00825     // Now check size.  It's only for display, so mismatch is not failure
00826     if (sqlSize != dtype->getOutputSize()) {
00827       m_matchReturn = MATCHcompatible;
00828     }
00829 
00830     return true;
00831   }

virtual bool rdbModel::MysqlConnection::close  )  [virtual]
 

Close the current open connection , if any. Return true if there was a connection to close and it was closed successfully

Implements rdbModel::Connection.

bool rdbModel::MysqlConnection::close  )  [virtual]
 

Close the current open connection , if any. Return true if there was a connection to close and it was closed successfully

Implements rdbModel::Connection.

00078                               {
00079     if (m_tempRes) {
00080       mysql_free_result(m_tempRes);
00081       m_tempRes = 0;
00082     }
00083  std::cout<<"close connection ================================"<<std::endl;
00084     mysql_close(m_mysql);
00085     m_mysql = 0;
00086     m_connected = false;
00087     return true;
00088   }

virtual bool rdbModel::MysqlConnection::compileAssertion const Assertion a,
std::string &  sqlString
const [virtual]
 

compile method for assertions. Use it internally, but also make it publicly available so assertions belonging to a table can save the compiled version.

Implements rdbModel::Connection.

bool rdbModel::MysqlConnection::compileAssertion const Assertion a,
std::string &  sqlString
const [virtual]
 

compile method for assertions. Use it internally, but also make it publicly available so assertions belonging to a table can save the compiled version.

Implements rdbModel::Connection.

00463                                   {
00464     if (!m_compileInit) {
00465       compileInit();
00466       m_compileInit = true;
00467     }
00468     try {
00469       return compileOperator(a->getOperator(), sqlString);
00470     }
00471     catch (RdbException ex) {
00472       (*m_out) << std::endl << ex.getMsg() << std::endl;
00473       m_out->flush();
00474       return false;
00475     }
00476   }

bool rdbModel::MysqlConnection::compileComparison Assertion::Operator op,
std::string &  sqlString
[static, private]
 

bool rdbModel::MysqlConnection::compileComparison Assertion::Operator op,
std::string &  sqlString
[static, private]
 

Result is appended to caller-supplied string Convention is to use " " around literal values Note no verification is done here; that operator is in fact a comparison or isNull operator. This is called internally only and that check will have been done before invoking this routine.

00510                             {
00511     if (op->getToBe()) return false;  // can't compile
00512 
00513     OPTYPE opType = op->getOpType();
00514     if (opType == OPTYPEisNull) {
00515       sqlString +="(";
00516       sqlString += op->getCompareArgs()[0];
00517       sqlString += opSymbols[opType];
00518       sqlString += ")";
00519       return true;
00520     }
00521     sqlString += "(";
00522 
00523     bool literal0 = (op->getCompareArgTypes()[0] == FIELDTYPElit);
00524     bool literal1 = (op->getCompareArgTypes()[1] == FIELDTYPElit);
00525 
00526     addArg(literal0, op->getCompareArgs()[0], sqlString);
00527     sqlString += opSymbols[opType];
00528     addArg(literal1, op->getCompareArgs()[1], sqlString);
00529     sqlString += ")";
00530 
00531     return true;
00532   }

void rdbModel::MysqlConnection::compileInit  )  [static, private]
 

void rdbModel::MysqlConnection::compileInit  )  [static, private]
 

00480                                     {
00481     opSymbols[OPTYPEor] = " OR ";
00482     opSymbols[OPTYPEand] = " AND ";
00483     opSymbols[OPTYPEnot] = " NOT ";
00484     opSymbols[OPTYPEexists] = "EXISTS ";
00485     opSymbols[OPTYPEisNull] = " IS NULL";
00486     opSymbols[OPTYPEequal] = "=";
00487     opSymbols[OPTYPEnotEqual] = "<>";
00488     opSymbols[OPTYPElessThan] = "<";
00489     opSymbols[OPTYPEgreaterThan] = ">";
00490     opSymbols[OPTYPElessOrEqual] = "<=";
00491     opSymbols[OPTYPEgreaterOrEqual] = ">=";
00492     return;
00493   }

bool rdbModel::MysqlConnection::compileOperator Assertion::Operator op,
std::string &  sqlString
[static, private]
 

bool rdbModel::MysqlConnection::compileOperator Assertion::Operator op,
std::string &  sqlString
[static, private]
 

00535                             {
00536 
00537     //maqm     std::cout<<"in compileOperator() sqlString is00:"<<sqlString<<std::endl;
00538     if (op->isCompareOp() ) return compileComparison(op, sqlString);
00539     if (op->getToBe()) return false;  // can't compile in this case
00540     bool ret = true;
00541 
00542     const std::vector<Assertion::Operator*>& children = op->getChildren();
00543     unsigned nChild = children.size();
00544 
00545     // For single-child operators NOT,  exists, operator symbol
00546     // goes 1st, then operand
00547     if (nChild <= 1) { // operator goes first
00548       sqlString += opSymbols[op->getOpType()];
00549 
00550       // more special handling for EXISTS
00551       if (op->getOpType() == OPTYPEexists) {
00552         sqlString += "(SELECT * FROM " + op->getTableName();
00553         if (!nChild) {     // done
00554           sqlString += ")";
00555           return ret;
00556         }
00557         // else EXISTS child is object of a WHERE clause 
00558         sqlString += " WHERE(";
00559       }
00560       ret = compileOperator(children[0], sqlString);
00561       if (!ret) {
00562         std::string msg = 
00563           "rdbModel::MysqlConnection::compileOperator failed for operator "
00564           + opSymbols[op->getOpType()];
00565         throw RdbException(msg);
00566       }
00567 
00568       // Have an extra closing ")" for EXISTS with WHERE clause
00569       if (op->getOpType() == OPTYPEexists)       sqlString += ")";
00570 
00571 
00572       return ret;
00573     }
00574 
00575     // Otherwise put operator symbols between adjacent children.
00576 
00577     // First open parentheses
00578     sqlString += "(";
00579 
00580     std::string symbol = opSymbols[op->getOpType()];
00581 
00582     ret = compileOperator(children[0], sqlString);
00583     if (!ret) {
00584       std::string msg = 
00585         "rdbModel::MysqlConnection::compileOperator failed for operator "
00586         + symbol;
00587       throw RdbException(msg);
00588     }
00589     for (unsigned int iChild = 1; iChild < nChild; iChild++) {
00590       sqlString += symbol;
00591 
00592       ret = compileOperator(children[iChild], sqlString);
00593       if (!ret) {
00594         std::string msg = 
00595           "rdbModel::MysqlConnection::compileOperator failed for operator "
00596           + symbol;
00597         throw RdbException(msg);
00598       }
00599     }
00600     // Finally close paren.
00601     sqlString += ")";
00602     return ret;
00603   }

virtual ResultHandle* rdbModel::MysqlConnection::dbRequest const std::string &  request  )  [virtual]
 

Transmit raw request of any form to our other end. If it is a request that returns results, those results will be stored in a newly-allocated ResultHandle and dbRequest will return a pointer to it. Otherwise dbRequest will return a null pointer. Throw an exception if request fails for any reason.

Implements rdbModel::Connection.

ResultHandle * rdbModel::MysqlConnection::dbRequest const std::string &  request  )  [virtual]
 

Transmit raw request of any form to our other end. If it is a request that returns results, those results will be stored in a newly-allocated ResultHandle and dbRequest will return a pointer to it. Otherwise dbRequest will return a null pointer. Throw an exception if request fails for any reason.

Implements rdbModel::Connection.

00408                                                                    {
00409 
00410     (*m_out) << std::endl << "# About to issue SQL request:" << std::endl;
00411     (*m_out) << request << std::endl;
00412     m_out->flush();
00413     
00414     int i=0;
00415     int mysqlRet = mysql_query(m_mysql, request.c_str());
00416     for (i=0;i<10;i++) {
00417     //  int mysqlRet = mysql_query(m_mysql, request.c_str());
00418       if (mysqlRet) {  
00419         //not connected
00420         std::string msg = 
00421           "rdbModel::MysqlConnection::dbRequest: mysql_query error, code ";
00422         std::string codeString;
00423         facilities::Util::itoa(mysqlRet, codeString);
00424         msg += codeString;
00425         (*m_out) << std::endl <<i<<"times not connected++++ "<< msg << std::endl;
00426         m_out->flush();
00427         fprintf(stderr, "mysql_query error %d: %s\n",mysql_errno(m_mysql),mysql_error(m_mysql));
00428         if (i>=9){
00429          throw RdbException(msg, mysqlRet);
00430           return 0;
00431         }
00432          mysql_close(m_mysql);
00433          m_mysql = 0;
00434          sleep(100);
00435          bool st = open(m_host,m_user,m_password,m_dbName);
00436          if(st==false) continue;
00437         mysqlRet = mysql_query(m_mysql, request.c_str());
00438       }else{
00439         break;
00440       }
00441     }
00442    
00443 
00444     MYSQL_RES *myres = mysql_store_result(m_mysql);
00445     if (!myres) {
00446       // Was it supposed to return data?
00447       if (mysql_field_count(m_mysql) == 0) { // no data expected
00448         return 0;
00449       }
00450       else {
00451         std::string msg =
00452           "rdbModel::MysqlConnection::dbRequest: expected data; none returned";
00453         (*m_out) << std::endl << msg << std::endl;
00454         m_out->flush();
00455         throw RdbException(msg);
00456         return 0;
00457       }
00458     }
00459     return new MysqlResults(myres);
00460   }

virtual void rdbModel::MysqlConnection::disableModify bool  disable  )  [inline, virtual]
 

Turn select and update into no-ops: output SQL string for debugging but don't change db

Implements rdbModel::Connection.

00137 {m_writeDisabled=disable;}

virtual void rdbModel::MysqlConnection::disableModify bool  disable  )  [inline, virtual]
 

Turn select and update into no-ops: output SQL string for debugging but don't change db

Implements rdbModel::Connection.

00137 {m_writeDisabled=disable;}

std::ostream* rdbModel::MysqlConnection::getErrOut  )  const [inline, virtual]
 

Implements rdbModel::Connection.

00057 {return m_err;}

std::ostream* rdbModel::MysqlConnection::getErrOut  )  const [inline, virtual]
 

Implements rdbModel::Connection.

00057 {return m_err;}

std::ostream* rdbModel::MysqlConnection::getOut  )  const [inline, virtual]
 

Implements rdbModel::Connection.

00056 {return m_out;}

std::ostream* rdbModel::MysqlConnection::getOut  )  const [inline, virtual]
 

Implements rdbModel::Connection.

00056 {return m_out;}

virtual bool rdbModel::MysqlConnection::insertRow const std::string &  tableName,
const StringVector colNames,
const StringVector values,
int *  auto_value = 0,
const StringVector nullCols = 0
[virtual]
 

Typical derived class will form a syntactically correct INSERT statement from the input arguments and issue it to the dbms. Return true if row was inserted successfully If auto_value is non-zero and the table has an auto-increment column, its value will be returned. If nullCols is non-zero, insertRow will treat each string in the vector as a column name whose value should be set to NULL

Might also want to add a routine for INSERT ... SELECT

Implements rdbModel::Connection.

bool rdbModel::MysqlConnection::insertRow const std::string &  tableName,
const StringVector colNames,
const StringVector values,
int *  auto_value = 0,
const StringVector nullCols = 0
[virtual]
 

Typical derived class will form a syntactically correct INSERT statement from the input arguments and issue it to the dbms. Return true if row was inserted successfully If auto_value is non-zero and the table has an auto-increment column, its value will be returned. If nullCols is non-zero, insertRow will treat each string in the vector as a column name whose value should be set to NULL

Might also want to add a routine for INSERT ... SELECT

Implements rdbModel::Connection.

00219                                                                 {
00220     std::string ins;
00221     if (auto_value) *auto_value = 0;
00222 
00223     // check that sizes of vectors match
00224     unsigned  nCol = colNames.size();    
00225     if (!nCol || (nCol != values.size()  ) ) {
00226       (*m_err) << " MysqlConnection::insertRow: vector lengths incompatible"
00227                 << std::endl;
00228       m_err->flush();
00229       return false;
00230     }
00231 
00232     // caller should already have checked for validity and should
00233     // have supplied all necessary columns
00234 
00235     ins += "insert into " + tableName;
00236     ins += " set " + colNames[0] + "='" + values[0] + "' ";
00237     for (unsigned iCol = 1; iCol < nCol; iCol++) {
00238       ins += ", " + colNames[iCol] + "='" + values[iCol] + "' ";
00239     }
00240     if (nullCols) {
00241       if (nullCols->size() > 0) {
00242         unsigned nNull = nullCols->size();
00243         for (unsigned iNull = 0; iNull < nNull; iNull++) {
00244           ins += ", " + (*nullCols)[iNull] + "= NULL ";
00245         }
00246       }
00247     }
00248 
00249     (*m_out) << std::endl << "# INSERT string is:" << std::endl;
00250     (*m_out) << ins << std::endl;
00251     m_out->flush();
00252 
00253     if (m_writeDisabled) {
00254       (*m_out) << "write to Db previously disabled; INSERT not sent"
00255                << std::endl;
00256       m_out->flush();
00257       return true;
00258     }
00259 
00260     int mysqlRet = mysql_query(m_mysql, ins.c_str());
00261 
00262     if (mysqlRet) {
00263       (*m_out) << "MySQL error during INSERT, code " << mysqlRet << std::endl;
00264       m_out->flush();
00265       return false;
00266     }
00267     if (auto_value) {
00268       *auto_value = mysql_insert_id(m_mysql);
00269     }
00270     return true;
00271   }

virtual bool rdbModel::MysqlConnection::isConnected  )  [inline, virtual]
 

Return true iff open has been done with no matching close.

Implements rdbModel::Connection.

00054 {return m_connected;}

virtual bool rdbModel::MysqlConnection::isConnected  )  [inline, virtual]
 

Return true iff open has been done with no matching close.

Implements rdbModel::Connection.

00054 {return m_connected;}

virtual MATCH rdbModel::MysqlConnection::matchSchema Rdb rdb,
bool  matchDbName = true
[virtual]
 

Check to what degree local schema definition is compatible with remote db accessed via this connection. By default check db names match, but this may be disabled.

If match is successful, may also want to cache information about some things; for example, rows for which agent = "service"

Implements rdbModel::Connection.

MATCH rdbModel::MysqlConnection::matchSchema Rdb rdb,
bool  matchDbName = true
[virtual]
 

Check to what degree local schema definition is compatible with remote db accessed via this connection. By default check db names match, but this may be disabled.

If match is successful, may also want to cache information about some things; for example, rows for which agent = "service"

Implements rdbModel::Connection.

00190                                                                {
00191     if (!m_connected) return MATCHnoConnection;
00192 
00193     m_matchDbName = matchDbName;
00194 
00195     // Check global characteristics; 
00196     // Could do this via Manager; seems a bit artificial, bypass for now
00197     m_visitorType = VISITORmatch;
00198     m_matchReturn = MATCHequivalent;
00199     unsigned int ret = rdb->accept(this);
00200 
00201     if ((ret == Visitor::VERROR) || (ret == Visitor::VERRORABORT)) {
00202       return MATCHfail;
00203     }
00204     else return m_matchReturn;
00205   }

virtual bool rdbModel::MysqlConnection::open const std::string &  parms  )  [virtual]
 

Parameter is normally path for an xml file descrbing the connection parameters

Implements rdbModel::Connection.

virtual bool rdbModel::MysqlConnection::open const std::string &  host,
const std::string &  userid,
const std::string &  password,
const std::string &  dbName
[virtual]
 

Implements rdbModel::Connection.

bool rdbModel::MysqlConnection::open const std::string &  parms  )  [virtual]
 

Parameter is normally path for an xml file descrbing the connection parameters

Implements rdbModel::Connection.

00162                                                    {
00163     using XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument;
00164     using XERCES_CPP_NAMESPACE_QUALIFIER DOMElement;
00165     xmlBase::XmlParser parser;
00166     DOMDocument* doc = parser.parse(parms.c_str(), "mysqlConnection");
00167     if (doc == 0) {
00168       (*m_err) << "parse of connection parameters failed" << std::endl;
00169       m_err->flush();
00170       return false;
00171     }
00172     DOMElement*  conn = doc->getDocumentElement();
00173     
00174     std::string host = xmlBase::Dom::getAttribute(conn, "host");
00175     std::string user = xmlBase::Dom::getAttribute(conn, "user");
00176     std::string password = xmlBase::Dom::getAttribute(conn, "password");
00177     std::string dbname = xmlBase::Dom::getAttribute(conn, "dbname");
00178 
00179     if (password.size() == 0 ) { // prompt for password?
00180       (*m_out) << "interactive login NYI " << std::endl;
00181       m_out->flush();
00182       return false;
00183     }
00184 
00185     return this->open(host, user, password, dbname);
00186   }

bool rdbModel::MysqlConnection::open const std::string &  host,
const std::string &  userid,
const std::string &  password,
const std::string &  dbName
[virtual]
 

Implements rdbModel::Connection.

00099                                                       {
00100                              //     , unsigned int       port) {
00101     if (dbName.size() == 0) {
00102       (*m_err) << 
00103         "rdbModel::MysqlConnection::open : null db name not allowed!" <<
00104         std::endl;
00105       m_err->flush();
00106       return false;
00107     } 
00108    //huangb add
00109     m_host = host;
00110     m_user = user;
00111     m_password = password;
00112 
00113     m_mysql = new MYSQL;
00114     mysql_init(m_mysql);
00115 
00116     // 'host' argument is of the form hostname[:port]
00117     //  That is, port section is optional.  If not supplied, use
00118     // default port.
00119     std::string hostOnly;
00120     int port = 0;
00121     unsigned int colonLoc = host.find(":");
00122     if (colonLoc == std::string::npos) {
00123       hostOnly = host;
00124     }
00125     else {
00126       hostOnly = host.substr(0, colonLoc);
00127       std::string portString = host.substr(colonLoc+1);
00128       try {
00129         port = facilities::Util::stringToInt(portString);
00130       }
00131       catch (facilities::WrongType ex) {
00132         (*m_err) << "From MysqlConnection::connect.  Bad port: "
00133                  << ex.getMsg() << std::endl;
00134         m_err->flush();
00135         return false;
00136       }
00137 
00138     }
00139     //    mysql_init(m_mysql);
00140     std::cout<<"host is:"<<hostOnly.c_str()<<"::use is:: "<<user.c_str()<<":pass is::"<<password.c_str()<<":db is::"<<dbName.c_str()<<std::endl;
00141     MYSQL *connected = mysql_real_connect(m_mysql, hostOnly.c_str(),  
00142                                           user.c_str(),
00143                                           password.c_str(), dbName.c_str(),
00144                                           3306, NULL, 0);
00145 
00146     if (connected != 0) {  // Everything is fine.  Put out an info message
00147       (*m_out) << "Successfully connected to MySQL host " << 
00148         host << ", database " << dbName << std::endl;
00149       m_out->flush();
00150       m_connected = true;
00151       m_dbName = dbName;
00152     }
00153     else {
00154       (*m_err) <<  "Failed to connect to MySQL host " << host <<
00155         "with error:::: " << mysql_error(m_mysql) << std::endl;
00156       m_err->flush();
00157       m_connected = false;
00158     }
00159     return m_connected;
00160   }

virtual ResultHandle* rdbModel::MysqlConnection::select const std::string &  tableName,
const StringVector getCols,
const StringVector orderCols,
const Assertion where = 0,
int  rowLimit = 0,
int  rowOffset = 0
[virtual]
 

Support only for relatively simple SELECT, involving just one table.

Parameters:
tableName 
getCols vector of columns to be retrieved
where ptr to an Assertion object
rowLimit max number of rows to return
rowOffset offset for first row returned among those satisfying conditions; ignored if 0.
Returns:
If the SELECT succeeds, a pointer to an object which manages the returned data; else 0. Caller is responsible for deleting the ResultHandle object.

Implements rdbModel::Connection.

ResultHandle * rdbModel::MysqlConnection::select const std::string &  tableName,
const StringVector getCols,
const StringVector orderCols,
const Assertion where = 0,
int  rowLimit = 0,
int  rowOffset = 0
[virtual]
 

Support only for relatively simple SELECT, involving just one table.

Parameters:
tableName 
getCols vector of columns to be retrieved
where ptr to an Assertion object
rowLimit max number of rows to return
rowOffset offset for first row returned among those satisfying conditions; ignored if 0.
Returns:
If the SELECT succeeds, a pointer to an object which manages the returned data; else 0. Caller is responsible for deleting the ResultHandle object.

Implements rdbModel::Connection.

00334                                                          {
00335     std::string sqlString = "SELECT ";
00336     unsigned nGet = getCols.size();
00337     unsigned nOrder = orderCols.size();
00338 
00339      std::cout<<"tableName is:"<<tableName<<std::endl;
00340 
00341 //     tableName="metadata_v2r1";
00342        
00343     sqlString += getCols[0];
00344     for (unsigned iGet = 1; iGet < nGet; iGet++) {
00345       sqlString += ",";
00346       sqlString += getCols[iGet];
00347     }
00348     sqlString +=  " FROM " + tableName +  " ";
00349      std::cout<<"sqlString is11:"<<sqlString<<std::endl;
00350    if (where != 0) {
00351       sqlString += " WHERE ";
00352       bool ret = compileAssertion(where, sqlString);
00353       if (!ret) return 0;
00354     }
00355    
00356     std::cout<<"sqlString is22:"<<sqlString<<std::endl;
00357   
00358     /*maqm  if (nOrder > 0 ) {
00359       sqlString += " ORDER BY " + orderCols[0]; 
00360       for (unsigned iOrder = 1; iOrder < nOrder; iOrder++) {
00361         sqlString += ",";
00362         sqlString += orderCols[iOrder];
00363       }
00364     }
00365    */ 
00366 //     sqlString ="SELECT ser_no FROM metadata_v2r1  WHERE ((completion='OK') AND (instrument='LAT') AND (calib_type='MDC_t0') AND (flavor='vanilla'))";
00367     if (rowLimit > 0) {
00368       // SQL format is LIMIT offset,limit      or
00369       //               LIMIT limit             or
00370       //               LIMIT limit   OFFSET offset  [don't use this one]
00371       sqlString += " LIMIT ";
00372       std::string limitStr;
00373       if (rowOffset > 0) {
00374         facilities::Util::itoa(rowOffset, limitStr);
00375         sqlString += limitStr + ",";
00376       }
00377       limitStr.clear();
00378       facilities::Util::itoa(rowLimit, limitStr);
00379        std::cout<<"limitStr is:"<<limitStr<<std::endl;
00380       sqlString += limitStr;
00381     }
00382 
00383     (*m_out) << std::endl << " # About to issue SELECT:" << std::endl;
00384     (*m_out) << sqlString << std::endl;
00385     m_out->flush();
00386    //maqm add
00387 //     sqlString="SELECT ser_no FROM metadata_v2r1";
00388 
00389      
00390     int mysqlRet = mysql_query(m_mysql, sqlString.c_str());
00391     if (mysqlRet) {
00392       std::string msg = 
00393         "rdbModel::MysqlConnection::select: mysql_query error, code ";
00394       std::string codeString;
00395       facilities::Util::itoa(mysqlRet, codeString);
00396       msg += codeString;
00397       (*m_out) << std::endl << msg << std::endl;
00398       m_out->flush();
00399       throw RdbException(msg, mysqlRet);
00400       return 0;
00401     }
00402 
00403     MYSQL_RES *myres = mysql_store_result(m_mysql);
00404     MysqlResults* results = new MysqlResults(myres);
00405     return results;
00406   }

virtual unsigned int rdbModel::MysqlConnection::update const std::string &  tableName,
const StringVector colNames,
const StringVector values,
const Assertion where = 0,
const StringVector nullCols = 0
[virtual]
 

Generic UPDATE. Return value is number of rows changed.

Implements rdbModel::Connection.

unsigned int rdbModel::MysqlConnection::update const std::string &  tableName,
const StringVector colNames,
const StringVector values,
const Assertion where = 0,
const StringVector nullCols = 0
[virtual]
 

Generic UPDATE. Return value is number of rows changed.

Implements rdbModel::Connection.

00278                                                                      {
00279 
00280     unsigned int nCol = colNames.size();
00281     if (nCol != values.size()) {
00282       (*m_err) << "rdbModel::mysqlConnection::update: ";
00283       (*m_err) << "Incompatible vector arguments " << std::endl;
00284       m_err->flush();
00285       return 0;
00286     }
00287     std::string sqlString = "UPDATE " + tableName + " SET ";
00288     sqlString += colNames[0] + " = '" + values[0] + "'";
00289     for (unsigned int iCol = 1; iCol < nCol; iCol++) {
00290       sqlString += "," + colNames[iCol] + " = '" + values[iCol] + "'";
00291     }
00292     if (nullCols) {
00293       unsigned nNull = nullCols->size();
00294       for (unsigned iNull = 0; iNull < nNull; iNull++) {
00295         sqlString += ", " + (*nullCols)[iNull] + "= NULL ";
00296       }
00297     }
00298 
00299     if (where) {
00300       sqlString += " WHERE ";
00301       bool ret = compileAssertion(where, sqlString);
00302       if (!ret) return 0;
00303     }
00304     (*m_out) << std::endl << "#  UPDATE to be issued:" << std::endl;
00305     (*m_out) << sqlString << std::endl;
00306     m_out->flush();
00307     if (m_writeDisabled) {
00308       (*m_out) << "write to Db previously disabled; UPDATE not sent"
00309                << std::endl;
00310       m_out->flush();
00311       return 0;
00312     }
00313     int mysqlRet = mysql_query(m_mysql, sqlString.c_str());
00314 
00315     if (mysqlRet) {
00316       (*m_out) << "rdbModel::MysqlConnection::update: ";
00317       (*m_out) << "MySQL error during UPDATE, code " << mysqlRet << std::endl;
00318       m_out->flush();
00319       return 0;
00320     }
00321     my_ulonglong nModLong = mysql_affected_rows(m_mysql);
00322     // Not much chance that we'll change more rows than will fit in just long
00323     unsigned nMod = nModLong;
00324     return nMod;
00325 
00326 
00327   }

virtual Visitor::VisitorState rdbModel::MysqlConnection::visitAssertion Assertion  )  [virtual]
 

Implements rdbModel::Visitor.

Visitor::VisitorState rdbModel::MysqlConnection::visitAssertion Assertion  )  [virtual]
 

Implements rdbModel::Visitor.

00840                                                                 {
00841     return Visitor::VCONTINUE;
00842   }

virtual Visitor::VisitorState rdbModel::MysqlConnection::visitColumn Column  )  [virtual]
 

Implements rdbModel::Visitor.

Visitor::VisitorState rdbModel::MysqlConnection::visitColumn Column  )  [virtual]
 

Implements rdbModel::Visitor.

00684                                                               {
00685     std::string myName = col->getName();
00686     if (m_colIx.find(myName) == m_colIx.end()) {
00687       m_matchReturn = MATCHfail;
00688       return Visitor::VERRORABORT;
00689     }
00690     unsigned int ix = m_colIx[myName];
00691     mysql_data_seek(m_tempRes, ix);
00692     MYSQL_ROW colDescrip = mysql_fetch_row(m_tempRes);
00693 
00694     // Type
00695     std::string sqlDtype = std::string(colDescrip[1]);
00696     Datatype* dtype = col->getDatatype();
00697     if (!checkDType(dtype, sqlDtype)) {
00698       m_matchReturn = MATCHfail;
00699       (*m_out) << "Failed dtype match of col " << myName << std::endl;
00700       return Visitor::VERRORABORT;
00701     }
00702 
00703     // Null
00704     bool nullable = (std::string(colDescrip[2]) == std::string("YES"));
00705     if (nullable != col->nullAllowed()) {
00706       m_matchReturn = MATCHfail;
00707       (*m_out) << "Failed null/not null match of col " << myName << std::endl;
00708       return Visitor::VERRORABORT;
00709     }
00710     // Key (PRI for primary, MUL if first in a multiple-field key
00711     // Save primary key info, if any
00712     if (std::string(colDescrip[3]) == std::string("PRI")) {
00713       m_primColName = myName;
00714     }
00715 
00716     // Field 4 is default
00717     // Extra (may say auto_increment)
00718     bool autoInc = 
00719       (std::string(colDescrip[5]) == std::string("auto_increment"));
00720     if (autoInc != col->isAutoIncrement()) {
00721       m_matchReturn = MATCHfail;
00722       (*m_out) << "Failed isAutoIncrement match of col " << myName << std::endl;
00723       return Visitor::VERRORABORT;
00724     }
00725     return Visitor::VCONTINUE;
00726   }

virtual Visitor::VisitorState rdbModel::MysqlConnection::visitIndex Index  )  [virtual]
 

Implements rdbModel::Visitor.

Visitor::VisitorState rdbModel::MysqlConnection::visitIndex Index  )  [virtual]
 

Implements rdbModel::Visitor.

00835                                                          {
00836     return Visitor::VCONTINUE;
00837     // might put something real here later
00838   }

virtual VisitorState rdbModel::MysqlConnection::visitInsertNew InsertNew  )  [virtual]
 

Implements rdbModel::Visitor.

Visitor::VisitorState rdbModel::MysqlConnection::visitInsertNew InsertNew  )  [virtual]
 

Implements rdbModel::Visitor.

00844                                                                 {
00845     return Visitor::VCONTINUE;
00846   }

virtual VisitorState rdbModel::MysqlConnection::visitInterRow InterRow  )  [virtual]
 

Implements rdbModel::Visitor.

Visitor::VisitorState rdbModel::MysqlConnection::visitInterRow InterRow  )  [virtual]
 

Implements rdbModel::Visitor.

00860                                                               {
00861     return Visitor::VCONTINUE;
00862   }

virtual VisitorState rdbModel::MysqlConnection::visitQuery Query  )  [virtual]
 

Implements rdbModel::Visitor.

Visitor::VisitorState rdbModel::MysqlConnection::visitQuery Query  )  [virtual]
 

Implements rdbModel::Visitor.

00852                                                         {
00853     return Visitor::VCONTINUE;
00854   }

virtual Visitor::VisitorState rdbModel::MysqlConnection::visitRdb Rdb  )  [virtual]
 

This method sets if the visitor is recursive or not.

Implements rdbModel::Visitor.

Visitor::VisitorState rdbModel::MysqlConnection::visitRdb Rdb  )  [virtual]
 

This method sets if the visitor is recursive or not.

Implements rdbModel::Visitor.

00608                                                         {
00609 
00610     if (m_matchDbName) {
00611       if (m_dbName != rdb->getDbName()) {
00612         m_matchReturn = MATCHfail;
00613         return Visitor::VDONE;
00614       }
00615     }
00616 
00617     unsigned int nLocal = rdb->getNTable();
00618 
00619     // Null pointer for 2nd argument means "list all tables"
00620 
00621     MYSQL_RES* res = mysql_list_tables(m_mysql, 0);
00622     if (!res) {
00623       m_matchReturn = MATCHfail;
00624       return Visitor::VERRORABORT;
00625     }
00626     unsigned int nRemote = mysql_num_rows(res);
00627     mysql_free_result(res);
00628 
00629     if (nRemote < nLocal) {
00630       m_matchReturn = MATCHfail;
00631       return Visitor::VDONE;
00632     }
00633     else if (nRemote > nLocal) m_matchReturn = MATCHcompatible;
00634 
00635     // Tell Rdb about this 
00636     rdb->setConnection(this);
00637 
00638     return Visitor::VCONTINUE;
00639   }

virtual VisitorState rdbModel::MysqlConnection::visitSet Set  )  [virtual]
 

Implements rdbModel::Visitor.

Visitor::VisitorState rdbModel::MysqlConnection::visitSet Set  )  [virtual]
 

Implements rdbModel::Visitor.

00856                                                     {
00857     return Visitor::VCONTINUE;
00858   }

virtual VisitorState rdbModel::MysqlConnection::visitSupersede Supersede  )  [virtual]
 

Implements rdbModel::Visitor.

Visitor::VisitorState rdbModel::MysqlConnection::visitSupersede Supersede  )  [virtual]
 

Implements rdbModel::Visitor.

00848                                                                 {
00849     return Visitor::VCONTINUE;
00850   }

virtual Visitor::VisitorState rdbModel::MysqlConnection::visitTable Table  )  [virtual]
 

Implements rdbModel::Visitor.

Visitor::VisitorState rdbModel::MysqlConnection::visitTable Table  )  [virtual]
 

Implements rdbModel::Visitor.

00641                                                               {
00642     const std::string& tName = table->getName();
00643 
00644     // Result set will have all fields for the table
00645     if (m_tempRes) {
00646       mysql_free_result(m_tempRes);
00647       m_tempRes = 0;
00648     }
00649     m_primColName.clear();
00650 
00651     std::string query = "SHOW COLUMNS FROM " + tName;
00652 
00653     (*m_out) << std::endl << "# About to issue SHOW COLUMNS request :" 
00654       << std::endl;
00655     (*m_out) << query << std::endl;
00656     m_out->flush();
00657 
00658     int ret = mysql_query(m_mysql, query.c_str());
00659     if (ret) {
00660       m_matchReturn = MATCHfail;
00661       return Visitor::VERRORABORT;
00662     }
00663 
00664     m_tempRes = mysql_store_result(m_mysql);
00665     if (!m_tempRes) {
00666       m_matchReturn = MATCHfail;
00667       return Visitor::VERRORABORT;
00668     }
00669     // Result set is a table with fields "Field"(the name) "Type" "Null"(yes
00670     // or no) "Key" "Default", "Extra"  
00671     // Make it easier for accept(Column* ) to find relevant information
00672     unsigned int nRow = mysql_num_rows(m_tempRes);
00673     m_colIx.clear();
00674     for (unsigned iRow = 0; iRow < nRow; iRow++) {
00675       MYSQL_ROW colDescrip = mysql_fetch_row(m_tempRes);
00676       std::string name = std::string(colDescrip[0]);
00677       std::cout<<"name is:"<<name<<std::endl;
00678       m_colIx[name] = iRow;
00679     }
00680     return Visitor::VCONTINUE;
00681 
00682   }


Member Data Documentation

std::map<std::string, unsigned int> rdbModel::MysqlConnection::m_colIx [private]
 

Index by colname; data is row number with "SHOW COLUMNS.." result set.

std::map<std::string, unsigned int> rdbModel::MysqlConnection::m_colIx [private]
 

Index by colname; data is row number with "SHOW COLUMNS.." result set.

bool rdbModel::MysqlConnection::m_compileInit = false [static, private]
 

bool rdbModel::MysqlConnection::m_connected [private]
 

std::string rdbModel::MysqlConnection::m_dbName [private]
 

std::ostream* rdbModel::MysqlConnection::m_err [private]
 

std::ostream* rdbModel::MysqlConnection::m_err [private]
 

std::string rdbModel::MysqlConnection::m_host [private]
 

bool rdbModel::MysqlConnection::m_matchDbName [private]
 

MATCH rdbModel::MysqlConnection::m_matchReturn [private]
 

Keep track of status during matching process.

MYSQL* rdbModel::MysqlConnection::m_mysql [private]
 

MYSQL* rdbModel::MysqlConnection::m_mysql [private]
 

std::vector<Column* > rdbModel::MysqlConnection::m_ourCols [private]
 

Also save list of columns we ("service") are responsible for Could organize this by table, or just use Column::getTableName()

std::vector<Column* > rdbModel::MysqlConnection::m_ourCols [private]
 

Also save list of columns we ("service") are responsible for Could organize this by table, or just use Column::getTableName()

std::ostream* rdbModel::MysqlConnection::m_out [private]
 

std::ostream* rdbModel::MysqlConnection::m_out [private]
 

std::string rdbModel::MysqlConnection::m_password [private]
 

std::string rdbModel::MysqlConnection::m_primColName [private]
 

Rdb* rdbModel::MysqlConnection::m_rdb [private]
 

If successful match, save pointer to schema for use with smart insert.

Rdb* rdbModel::MysqlConnection::m_rdb [private]
 

If successful match, save pointer to schema for use with smart insert.

MYSQL_RES* rdbModel::MysqlConnection::m_tempRes [private]
 

For query results while visiting.

MYSQL_RES* rdbModel::MysqlConnection::m_tempRes [private]
 

For query results while visiting.

std::string rdbModel::MysqlConnection::m_user [private]
 

VISITOR rdbModel::MysqlConnection::m_visitorType [private]
 

bool rdbModel::MysqlConnection::m_writeDisabled [private]
 


The documentation for this class was generated from the following files:
Generated on Wed Feb 2 19:22:28 2011 for BOSS6.5.5 by  doxygen 1.3.9.1