NightGetDBImpl.h 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. #ifndef NIGHT_GET_DB_IMPL_H
  2. #define NIGHT_GET_DB_IMPL_H
  3. #include <list>
  4. #include <map>
  5. using namespace std;
  6. #include <iostream>
  7. #include <tr1/memory>
  8. using namespace tr1;
  9. #include <mysql/mysql.h>
  10. #include "NightGetDatabase.h"
  11. #include "NightGetConverter.h"
  12. #include "NightGetUtilities.h"
  13. /*
  14. Implementation of NightGetDatabase for MySQL server using MySQL C API
  15. Attention: queries and names of table(s) are hardcoded here
  16. ./db.cnf - file where configuration data for connecting resides
  17. */
  18. template<typename Object, template <typename T> class ConvType, THREAD_POLICY tp>
  19. class MySQLNightGetDatabase: public NightGetDatabase<Object,ConvType,tp> {
  20. public:
  21. MySQLNightGetDatabase();
  22. ~MySQLNightGetDatabase() throw();
  23. private:
  24. MySQLNightGetDatabase(const MySQLNightGetDatabase&);
  25. MySQLNightGetDatabase& operator=(const MySQLNightGetDatabase&);
  26. int do_countObjects();
  27. list<shared_ptr<Object> > do_getObjects();
  28. int do_save(const Object& data);
  29. int do_startThread() const;
  30. int do_endThread() const;
  31. bool checklib() const { return (tp==threads)? mysql_thread_safe():true; };
  32. MYSQL* _handler;
  33. };
  34. template<typename Object, template <typename T> class ConvType, THREAD_POLICY tp>
  35. MySQLNightGetDatabase<Object,ConvType,tp>::MySQLNightGetDatabase():
  36. NightGetDatabase<Object,ConvType,tp>(),
  37. _handler(0) {
  38. if (this->checklib()) {
  39. #ifndef NDEBUG
  40. cerr << "\nNightGet: Connecting to MySQL...\n";
  41. #endif
  42. if ( mysql_library_init(0, NULL, NULL)!=0 )
  43. throw DBException("MySQL library is silent");
  44. _handler = mysql_init(NULL);
  45. if (!_handler)
  46. throw DBException("there is no memory for mysql connection");
  47. mysql_options(_handler, MYSQL_READ_DEFAULT_FILE,"./db.cnf");
  48. if ( (_handler = mysql_real_connect( _handler, NULL, NULL, NULL, NULL, 0, NULL, 0 )) == NULL)
  49. throw DBException("can't connect to the MySQL");
  50. #ifndef NDEBUG
  51. cerr << "\nNightGet: Connecting to MySQL successful.\n";
  52. #endif
  53. } else throw DBException("this library is not suited for threads");
  54. };
  55. template<typename Object, template <typename T> class ConvType, THREAD_POLICY tp>
  56. MySQLNightGetDatabase<Object,ConvType,tp>::~MySQLNightGetDatabase() throw() {
  57. mysql_close(_handler);
  58. mysql_library_end();
  59. #ifndef NDEBUG
  60. cerr << "\nNightGet: Disconnecting from MySQL successful.\n";
  61. #endif
  62. };
  63. template<typename Object, template <typename T> class ConvType, THREAD_POLICY tp>
  64. int MySQLNightGetDatabase<Object,ConvType,tp>::do_countObjects() {
  65. // string query = "select count(id) from nightload where state='init' or state='started'";
  66. string query = "select count(id) from nightload where state='init'";
  67. /*unsigned long length = query.length();
  68. char* escaped_q = new char [length*2+1];
  69. mysql_real_escape_string(_handler, escaped_q, query.c_str(), length);*/
  70. #ifndef NDEBUG
  71. cerr << "\nNightGet: Executing query to MySQL: " << query << endl;
  72. #endif
  73. if( mysql_query(_handler, query.c_str()) != 0 ) {
  74. throw DBException(mysql_error(_handler));
  75. return -1;
  76. }
  77. MYSQL_RES* result = mysql_store_result(_handler);
  78. if (!result) {
  79. throw DBException(mysql_error(_handler));
  80. return -1;
  81. }
  82. return string2int(mysql_fetch_row(result)[0]);
  83. };
  84. template<typename Object, template <typename T> class ConvType, THREAD_POLICY tp>
  85. list<shared_ptr<Object> > MySQLNightGetDatabase<Object,ConvType,tp>::do_getObjects() {
  86. // string query = "select url,path,id,protocol from nightload where (state='init' or state='started') " + NightGetDatabase<Object,ConvType,tp>::_converter->getComparison();
  87. string query = "select url,path,id,protocol from nightload where state='init' "+NightGetDatabase<Object,ConvType,tp>::_converter->getComparison();
  88. #ifndef NDEBUG
  89. cerr << "\nNightGet: Executing query to MySQL: " << query << endl;
  90. #endif
  91. if( mysql_query(_handler, query.c_str()) != 0 ) {
  92. throw DBException(mysql_error(_handler));
  93. return list<shared_ptr<Object> >();
  94. }
  95. MYSQL_RES* result = mysql_store_result(_handler);
  96. if (!result) {
  97. throw DBException(mysql_error(_handler));
  98. return list<shared_ptr<Object> >();
  99. }
  100. MYSQL_ROW r;
  101. unsigned int fields = mysql_field_count(_handler);
  102. unsigned int rows = mysql_num_rows(result);
  103. MYSQL_FIELD* names = mysql_fetch_fields(result);
  104. list<shared_ptr<Object> > objects;
  105. while (rows--) {
  106. try {
  107. map<string,string> mapped_record;
  108. r = mysql_fetch_row(result);
  109. for (unsigned int i = 0; i<fields; ++i)
  110. mapped_record[names[i].name] = r[i];
  111. shared_ptr<Object> p(NightGetDatabase<Object,ConvType,tp>::_converter->convertFromDB(mapped_record));
  112. objects.push_back(p);
  113. } catch (BrokenDBObject& e) {
  114. log(e.what());
  115. break;
  116. }
  117. }
  118. mysql_free_result(result);
  119. return objects;
  120. }
  121. template<typename Object, template <typename T> class ConvType, THREAD_POLICY tp>
  122. int MySQLNightGetDatabase<Object,ConvType,tp>::do_save(const Object& data) {
  123. string date = get_today();
  124. try {
  125. map<string,string> mapped = NightGetDatabase<Object,ConvType,tp>::_converter->convertForDB(data);
  126. //TODO make prepared statement
  127. string query = "update nightload set state='"+mapped["state"]+"', path='"+mapped["path"]+"', finish='"+date+"', url='"+mapped["url"]+"' where id='"+mapped["id"]+"'";
  128. #ifndef NDEBUG
  129. cerr << "\nNightGet: Executing query to MySQL: " << query << endl;
  130. #endif
  131. if( mysql_query(_handler, query.c_str()) != 0 ) {
  132. throw DBException(mysql_error(_handler));
  133. return -1;
  134. }
  135. } catch (BrokenDBObject& e) {
  136. string s (string ("error during saving to database: ")+e.what());
  137. log (s.c_str());
  138. throw NightGetException(s.c_str());
  139. return -1;
  140. }
  141. return 0;
  142. }
  143. template<typename Object, template <typename T> class ConvType, THREAD_POLICY tp>
  144. int MySQLNightGetDatabase<Object,ConvType,tp>::do_startThread() const {
  145. if (mysql_thread_init() != 0) {
  146. throw DBException(mysql_error(_handler));
  147. return -1;
  148. }
  149. return 0;
  150. }
  151. template<typename Object, template <typename T> class ConvType, THREAD_POLICY tp>
  152. int MySQLNightGetDatabase<Object,ConvType,tp>::do_endThread() const {
  153. mysql_thread_end();
  154. return 0;
  155. }
  156. #endif // NIGHT_GET_DB_IMPL_H