27 int extractSize(
const std::string& sqlString) {
28 std::string::size_type leftLoc = sqlString.find(
"(");
29 if (leftLoc == std::string::npos)
return 0;
31 std::string::size_type rightLoc = sqlString.find(
",");
32 if (rightLoc == std::string::npos) {
33 rightLoc = sqlString.find(
")");
35 std::string numString =
36 sqlString.substr(leftLoc, rightLoc - leftLoc);
40 void addArg(
bool literal,
const std::string
arg, std::string& sqlString) {
41 if (literal) sqlString +=
'"';
43 if (literal) sqlString +=
'"';
47 bool compareEnumList(
const std::vector<std::string>& choices,
48 std::string sqlType) {
50 std::string::size_type locComma = sqlType.find(
",");
52 while (locComma != std::string::npos) {
54 locComma = sqlType.find(
",", locComma+1);
56 unsigned nChoice = choices.size();
57 if (nChoice != (nComma + 1))
return false;
58 for (
unsigned iChoice = 0; iChoice < nChoice; iChoice++) {
59 std::string::size_type loc = sqlType.find(choices[iChoice]);
60 if (loc == std::string::npos)
return false;
67 bool MysqlConnection::m_compileInit =
false;
70 std::ostream* errOut) :
71 m_mysql(0), m_connected(0),
m_out(out), m_err(errOut),
72 m_visitorType(VISITORundefined), m_rdb(0), m_tempRes(0),
73 m_writeDisabled(
false) {
74 if (m_out == 0) m_out = &std::cout;
75 if (m_err == 0) m_err = &std::cerr;
80 mysql_free_result(m_tempRes);
83 std::cout<<
"close connection ================================"<<std::endl;
97 const std::string& user,
98 const std::string& password,
99 const std::string& dbName) {
101 if (dbName.size() == 0) {
103 "rdbModel::MysqlConnection::open : null db name not allowed!" <<
111 m_password = password;
119 std::string hostOnly;
121 std::string::size_type colonLoc = host.find(
":");
122 if (colonLoc == std::string::npos) {
126 hostOnly = host.substr(0, colonLoc);
127 std::string portString = host.substr(colonLoc+1);
132 (*m_err) <<
"From MysqlConnection::connect. Bad port: "
133 << ex.
getMsg() << std::endl;
140 std::cout<<
"host is:"<<hostOnly.c_str()<<
"::use is:: "<<user.c_str()<<
":pass is::"<<password.c_str()<<
":db is::"<<dbName.c_str()<<std::endl;
141 MYSQL *connected = mysql_real_connect(m_mysql, hostOnly.c_str(),
143 password.c_str(), dbName.c_str(),
146 if (connected != 0) {
147 (*m_out) <<
"Successfully connected to MySQL host " <<
148 host <<
", database " << dbName << std::endl;
154 (*m_err) <<
"Failed to connect to MySQL host " << host <<
155 "with error:::: " << mysql_error(m_mysql) << std::endl;
163 using XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument;
164 using XERCES_CPP_NAMESPACE_QUALIFIER DOMElement;
166 DOMDocument* doc = parser.
parse(parms.c_str(),
"mysqlConnection");
168 (*m_err) <<
"parse of connection parameters failed" << std::endl;
172 DOMElement* conn = doc->getDocumentElement();
179 if (password.size() == 0 ) {
180 (*m_out) <<
"interactive login NYI " << std::endl;
185 return this->
open(host, user, password, dbname);
193 m_matchDbName = matchDbName;
197 m_visitorType = VISITORmatch;
199 unsigned int ret = rdb->
accept(
this);
204 else return m_matchReturn;
221 if (auto_value) *auto_value = 0;
224 unsigned nCol = colNames.size();
225 if (!nCol || (nCol != values.size() ) ) {
226 (*m_err) <<
" MysqlConnection::insertRow: vector lengths incompatible"
235 ins +=
"insert into " + tableName;
236 ins +=
" set " + colNames[0] +
"='" + values[0] +
"' ";
237 for (
unsigned iCol = 1; iCol < nCol; iCol++) {
238 ins +=
", " + colNames[iCol] +
"='" + values[iCol] +
"' ";
241 if (nullCols->size() > 0) {
242 unsigned nNull = nullCols->size();
243 for (
unsigned iNull = 0; iNull < nNull; iNull++) {
244 ins +=
", " + (*nullCols)[iNull] +
"= NULL ";
249 (*m_out) << std::endl <<
"# INSERT string is:" << std::endl;
250 (*m_out) << ins << std::endl;
253 if (m_writeDisabled) {
254 (*m_out) <<
"write to Db previously disabled; INSERT not sent"
260 int mysqlRet = mysql_query(m_mysql, ins.c_str());
263 (*m_out) <<
"MySQL error during INSERT, code " << mysqlRet << std::endl;
268 *auto_value = mysql_insert_id(m_mysql);
280 unsigned int nCol = colNames.size();
281 if (nCol != values.size()) {
282 (*m_err) <<
"rdbModel::mysqlConnection::update: ";
283 (*m_err) <<
"Incompatible vector arguments " << std::endl;
287 std::string sqlString =
"UPDATE " + tableName +
" SET ";
288 sqlString += colNames[0] +
" = '" + values[0] +
"'";
289 for (
unsigned int iCol = 1; iCol < nCol; iCol++) {
290 sqlString +=
"," + colNames[iCol] +
" = '" + values[iCol] +
"'";
293 unsigned nNull = nullCols->size();
294 for (
unsigned iNull = 0; iNull < nNull; iNull++) {
295 sqlString +=
", " + (*nullCols)[iNull] +
"= NULL ";
300 sqlString +=
" WHERE ";
304 (*m_out) << std::endl <<
"# UPDATE to be issued:" << std::endl;
305 (*m_out) << sqlString << std::endl;
307 if (m_writeDisabled) {
308 (*m_out) <<
"write to Db previously disabled; UPDATE not sent"
313 int mysqlRet = mysql_query(m_mysql, sqlString.c_str());
316 (*m_out) <<
"rdbModel::MysqlConnection::update: ";
317 (*m_out) <<
"MySQL error during UPDATE, code " << mysqlRet << std::endl;
321 my_ulonglong nModLong = mysql_affected_rows(m_mysql);
323 unsigned nMod = nModLong;
335 std::string sqlString =
"SELECT ";
336 unsigned nGet = getCols.size();
337 unsigned nOrder = orderCols.size();
339 std::cout<<
"tableName is:"<<tableName<<std::endl;
343 sqlString += getCols[0];
344 for (
unsigned iGet = 1; iGet < nGet; iGet++) {
346 sqlString += getCols[iGet];
348 sqlString +=
" FROM " + tableName +
" ";
349 std::cout<<
"sqlString is11:"<<sqlString<<std::endl;
351 sqlString +=
" WHERE ";
356 std::cout<<
"sqlString is22:"<<sqlString<<std::endl;
371 sqlString +=
" LIMIT ";
372 std::string limitStr;
375 sqlString += limitStr +
",";
379 std::cout<<
"limitStr is:"<<limitStr<<std::endl;
380 sqlString += limitStr;
383 (*m_out) << std::endl <<
" # About to issue SELECT:" << std::endl;
384 (*m_out) << sqlString << std::endl;
390 int mysqlRet = mysql_query(m_mysql, sqlString.c_str());
393 "rdbModel::MysqlConnection::select: mysql_query error, code ";
394 std::string codeString;
397 (*m_out) << std::endl << msg << std::endl;
403 MYSQL_RES *myres = mysql_store_result(m_mysql);
410 (*m_out) << std::endl <<
"# About to issue SQL request:" << std::endl;
411 (*m_out) << request << std::endl;
415 int mysqlRet = mysql_query(m_mysql, request.c_str());
421 "rdbModel::MysqlConnection::dbRequest: mysql_query error, code ";
422 std::string codeString;
425 (*m_out) << std::endl <<i<<
"times not connected++++ "<< msg << std::endl;
427 fprintf(stderr,
"mysql_query error %d: %s\n",mysql_errno(m_mysql),mysql_error(m_mysql));
432 mysql_close(m_mysql);
435 bool st =
open(m_host,m_user,m_password,m_dbName);
436 if(st==
false)
continue;
437 mysqlRet = mysql_query(m_mysql, request.c_str());
444 MYSQL_RES *myres = mysql_store_result(m_mysql);
447 if (mysql_field_count(m_mysql) == 0) {
452 "rdbModel::MysqlConnection::dbRequest: expected data; none returned";
453 (*m_out) << std::endl << msg << std::endl;
463 std::string& sqlString)
const {
464 if (!m_compileInit) {
466 m_compileInit =
true;
469 return compileOperator(a->
getOperator(), sqlString);
472 (*m_out) << std::endl << ex.
getMsg() << std::endl;
480 void MysqlConnection::compileInit() {
509 bool MysqlConnection::compileComparison(Assertion::Operator* op,
510 std::string& sqlString) {
511 if (op->getToBe())
return false;
513 OPTYPE opType = op->getOpType();
516 sqlString += op->getCompareArgs()[0];
523 bool literal0 = (op->getCompareArgTypes()[0] ==
FIELDTYPElit);
524 bool literal1 = (op->getCompareArgTypes()[1] ==
FIELDTYPElit);
526 addArg(literal0, op->getCompareArgs()[0], sqlString);
528 addArg(literal1, op->getCompareArgs()[1], sqlString);
534 bool MysqlConnection::compileOperator(Assertion::Operator* op,
535 std::string &sqlString) {
538 if (op->isCompareOp() )
return compileComparison(op, sqlString);
539 if (op->getToBe())
return false;
542 const std::vector<Assertion::Operator*>& children = op->getChildren();
543 unsigned nChild = children.size();
552 sqlString +=
"(SELECT * FROM " + op->getTableName();
558 sqlString +=
" WHERE(";
560 ret = compileOperator(children[0], sqlString);
563 "rdbModel::MysqlConnection::compileOperator failed for operator "
565 throw RdbException(msg);
580 std::string symbol =
opSymbols[op->getOpType()];
582 ret = compileOperator(children[0], sqlString);
585 "rdbModel::MysqlConnection::compileOperator failed for operator "
587 throw RdbException(msg);
589 for (
unsigned int iChild = 1; iChild < nChild; iChild++) {
592 ret = compileOperator(children[iChild], sqlString);
595 "rdbModel::MysqlConnection::compileOperator failed for operator "
597 throw RdbException(msg);
621 MYSQL_RES* res = mysql_list_tables(m_mysql, 0);
626 unsigned int nRemote = mysql_num_rows(res);
627 mysql_free_result(res);
629 if (nRemote < nLocal) {
642 const std::string& tName = table->
getName();
646 mysql_free_result(m_tempRes);
649 m_primColName.clear();
651 std::string query =
"SHOW COLUMNS FROM " + tName;
653 (*m_out) << std::endl <<
"# About to issue SHOW COLUMNS request :"
655 (*m_out) << query << std::endl;
658 int ret = mysql_query(m_mysql, query.c_str());
664 m_tempRes = mysql_store_result(m_mysql);
672 unsigned int nRow = mysql_num_rows(m_tempRes);
674 for (
unsigned iRow = 0; iRow < nRow; iRow++) {
675 MYSQL_ROW colDescrip = mysql_fetch_row(m_tempRes);
676 std::string name = std::string(colDescrip[0]);
677 std::cout<<
"name is:"<<name<<std::endl;
678 m_colIx[name] = iRow;
685 std::string myName = col->
getName();
686 if (m_colIx.find(myName) == m_colIx.end()) {
690 unsigned int ix = m_colIx[myName];
691 mysql_data_seek(m_tempRes, ix);
692 MYSQL_ROW colDescrip = mysql_fetch_row(m_tempRes);
695 std::string sqlDtype = std::string(colDescrip[1]);
697 if (!checkDType(dtype, sqlDtype)) {
699 (*m_out) <<
"Failed dtype match of col " << myName << std::endl;
704 bool nullable = (std::string(colDescrip[2]) == std::string(
"YES"));
707 (*m_out) <<
"Failed null/not null match of col " << myName << std::endl;
712 if (std::string(colDescrip[3]) == std::string(
"PRI")) {
713 m_primColName = myName;
719 (std::string(colDescrip[5]) == std::string(
"auto_increment"));
722 (*m_out) <<
"Failed isAutoIncrement match of col " << myName << std::endl;
728 bool MysqlConnection::checkDType(
Datatype* dtype,
729 const std::string& sqlType) {
733 sqlSize = extractSize(sqlType);
742 if (sqlType.find(base) != 0) {
746 Enum* ourEnum = dtype->
getEnum();
749 return compareEnumList(ourEnum->getChoices(), sqlType);
753 if (sqlType.find(base) != 0) {
758 if (sqlSize < dtype->getOutputSize()) {
769 if (sqlType.find(base) != 0) {
774 if (!sqlSize) sqlSize = 1;
776 if (sqlSize < dtype->getOutputSize()) {
786 if (sqlType !=
"datetime") {
821 if (sqlType.find(base) != 0) {
*******DOUBLE PRECISION m_EGridB INTEGER m_out
double arg(const EvtComplex &c)
struct st_mysql_res MYSQL_RES
static int stringToInt(const std::string &InStr)
static const char * itoa(int val, std::string &outStr)
Exception class used when converting from string to numeric type.
Operator * getOperator() const
Datatype * getDatatype() const
bool isAutoIncrement() const
const std::string & getName() const
bool nullAllowed() const
Returns true if column may take on value NULL.
int getOutputSize() const
virtual VisitorState visitInterRow(InterRow *)
virtual Visitor::VisitorState visitRdb(Rdb *)
This method says if the visitor is recursive or not.
virtual Visitor::VisitorState visitAssertion(Assertion *)
virtual VisitorState visitQuery(Query *)
virtual VisitorState visitSet(Set *)
virtual bool open(const std::string &host, const std::string &userid, const std::string &password, const std::string &dbName)
virtual ResultHandle * select(const std::string &tableName, const StringVector &getCols, const StringVector &orderCols, const Assertion *where=0, int rowLimit=0, int rowOffset=0)
virtual Visitor::VisitorState visitTable(Table *)
virtual Visitor::VisitorState visitIndex(Index *)
virtual bool compileAssertion(const Assertion *a, std::string &sqlString) const
virtual VisitorState visitSupersede(Supersede *)
virtual ResultHandle * dbRequest(const std::string &request)
virtual VisitorState visitInsertNew(InsertNew *)
virtual ~MysqlConnection()
virtual MATCH matchSchema(Rdb *rdb, bool matchDbName=true)
virtual bool insertRow(const std::string &tableName, const StringVector &colNames, const StringVector &values, int *auto_value=0, const StringVector *nullCols=0)
virtual Visitor::VisitorState visitColumn(Column *)
virtual unsigned int update(const std::string &tableName, const StringVector &colNames, const StringVector &values, const Assertion *where=0, const StringVector *nullCols=0)
MysqlConnection(std::ostream *out=0, std::ostream *errOut=0)
virtual std::string getMsg()
const std::string & getDbName()
unsigned int getNTable() const
void setConnection(Connection *connection)
unsigned int accept(Visitor *v)
This is the recursive accept for the visitor pattern.
const std::string & getName() const
static std::string getAttribute(const DOMElement *elt, const char *attName)
DOMDocument * parse(const char *const filename, const std::string &docType=std::string(""))
Parse an xml file, returning document node if successful.
std::string opSymbols[OPTYPElast]
std::vector< std::string > StringVector