Back to index

nordugrid-arc-nox  1.1.0~rc6
MysqlWrapper.cpp
Go to the documentation of this file.
00001 // -*- indent-tabs-mode: nil -*-
00002 
00003 #ifdef HAVE_CONFIG_H
00004 #include <config.h>
00005 #endif
00006 
00007 #include <iostream>
00008 #include "MysqlWrapper.h"
00009 
00010 namespace Arc {
00011   MySQLDatabase::MySQLDatabase(std::string& server, int port)
00012     : server_(server),
00013       port_(port),
00014       mysql(NULL),
00015       is_connected(false)
00016   {}
00017 
00018   MySQLDatabase::MySQLDatabase(const MySQLDatabase& other)
00019     : is_connected(false) {
00020     if (other.isconnected()) {
00021       if (isconnected())
00022         close();
00023       mysql_real_connect(mysql, other.server_.c_str(), other.user_.c_str(),
00024                          other.password_.c_str(), other.dbname_.c_str(), other.port_, NULL, 0);
00025       if(mysql == NULL) is_connected = false;
00026       else is_connected = true;
00027     }
00028     else
00029       is_connected = false;
00030   }
00031 
00032   MySQLDatabase::~MySQLDatabase() {
00033     if (isconnected())
00034       close();
00035   }
00036 
00037   bool MySQLDatabase::connect(std::string& dbname, std::string& user, std::string& password) {
00038     mysql = mysql_init(NULL);
00039     if (!mysql_real_connect(mysql, server_.c_str(), user.c_str(), password.c_str(), dbname.c_str(), port_, NULL, 0)) {
00040       std::cerr << "Database connection failed" << std::endl;
00041       return false;
00042     }
00043     is_connected = true;
00044     return true;
00045   }
00046 
00047   void MySQLDatabase::close() {
00048     if (mysql)
00049       mysql_close(mysql);
00050     mysql = NULL;
00051     is_connected = false;
00052   }
00053 
00054   bool MySQLDatabase::enable_ssl(const std::string keyfile, const std::string certfile,
00055                                  const std::string cafile, const std::string capath) {
00056     return mysql_ssl_set(mysql, keyfile.c_str(), certfile.c_str(), cafile.c_str(), capath.c_str(), NULL) == 0;
00057 
00058   }
00059 
00060   bool MySQLDatabase::shutdown() {
00061     return mysql_shutdown(mysql, SHUTDOWN_DEFAULT);
00062 
00063   }
00064 
00065 
00066   MySQLQuery::MySQLQuery(Database *db)
00067     : db_(NULL), res(NULL) {
00068     MySQLDatabase *database = NULL;
00069     database = dynamic_cast<MySQLDatabase*>(db);
00070     if(database == NULL) std::cerr<<"The parameter of constructor should be MySQLDatabase type"<<std::endl;
00071     //  db_ = new MySQLDatabase(*database);
00072     db_ = database;
00073   }
00074 
00075   MySQLQuery::~MySQLQuery() {
00076     //  if(db_!=NULL) delete db_;
00077     db_ == NULL;
00078     if (res)
00079       mysql_free_result(res);
00080   }
00081 
00082   bool MySQLQuery::execute(const std::string& sqlstr) {
00083     //std::cout << "Query: " << sqlstr << std::endl;
00084     if (db_->mysql == NULL)
00085       std::cerr << "mysql object is NULL" << std::endl;
00086     if (mysql_query(db_->mysql, sqlstr.c_str())) {
00087       std::cerr << "Database query failed" << std::endl;
00088       return false;
00089     }
00090     res = mysql_store_result(db_->mysql);
00091     if (res) {
00092       num_colums = 0;
00093       MYSQL_FIELD *field = NULL;
00094       while (true) {
00095         field = mysql_fetch_field(res);
00096         if (field) {
00097           if (field->name)
00098             field_names[field->name] = num_colums;
00099           num_colums++;
00100         }
00101         else
00102           break;
00103       }
00104       num_rows = mysql_num_rows(res);
00105     }
00106     return true;
00107   }
00108 
00109   int MySQLQuery::get_num_colums() {
00110     return num_colums;
00111   }
00112 
00113   int MySQLQuery::get_num_rows() {
00114     return num_rows;
00115   }
00116 
00117   QueryRowResult MySQLQuery::get_row(int row_number) const {
00118     mysql_data_seek(res, row_number);
00119     return get_row();
00120   }
00121 
00122   QueryRowResult MySQLQuery::get_row() const {
00123     MYSQL_ROW row = mysql_fetch_row(res);
00124     QueryRowResult row_value;
00125     if (row == NULL)
00126       return row_value;
00127 
00128     std::string field;
00129     for (int i = 0; i < num_colums; i++) {
00130       if(row[i] == NULL) field="";
00131       else field = row[i];
00132       row_value.push_back(field);
00133     }
00134     return row_value;
00135   }
00136 
00137   std::string MySQLQuery::get_row_field(int row_number, std::string& field_name) {
00138     int field_number = field_names[field_name];
00139     QueryRowResult row_value = get_row(row_number);
00140     return row_value[field_number];
00141   }
00142 
00143   bool MySQLQuery::get_array(std::string& sqlstr, QueryArrayResult& result, std::vector<std::string>& arguments) {
00144     //replace the "?" in sql sentence with the values from argument of this method.
00145     //e.g. if the sql sentence is "select table.value from table where table.name = ?",
00146     //and the third argument of this method is std::string& name, then the "name" will replace
00147     //the "?" in the above sql sentence.
00148     //The repalacement will be sequentially done, which means the first argument in the vector will replace
00149     //the first "?" in sql sentence, and the second one will replace the second "?".
00150     //The values inside the third arguments--"arguments" should all be std::string type, since we will not
00151     //distinguish them in this method itself.
00152     std::string arg_str;
00153     size_t found = std::string::npos;
00154     int i = 0;
00155     while (true) {
00156       if (i < arguments.size())
00157         arg_str = arguments[i++];
00158       else
00159         arg_str = "";
00160       found = sqlstr.find("?", found + 1);
00161       if ((found != std::string::npos) && arg_str.empty()) {
00162         std::cerr << "There is no enough arguments given in method: MySQLQuery::getarray " << std::endl;
00163         return false;
00164       }
00165       if (found == std::string::npos)
00166         break;
00167       sqlstr.replace(found, 1, arg_str);
00168     }
00169 
00170     //std::cout << "The sql sentence after replacement: " << sqlstr << std::endl;
00171     QueryRowResult row_value;
00172     if (execute(sqlstr)) {
00173       int rows = get_num_rows();
00174       for (int i = 0; i < rows; i++) {
00175         row_value = get_row();
00176         result.push_back(row_value);
00177       }
00178       return true;
00179     }
00180     return false;
00181   }
00182 
00183 } // namespace Arc