ModuleSQL.cpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. #include "ModuleBase.h"
  2. #include <iostream>
  3. #include <string>
  4. #include <sqlite3.h>
  5. #include <boost/algorithm/string.hpp>
  6. namespace mdd {
  7. class ModuleSQL : public ModuleBase {
  8. private:
  9. std::string _dbname;
  10. sqlite3* _db;
  11. std::string _tbname;
  12. void erase_keyword(std::string& str, std::string key);
  13. struct _entity {
  14. std::string key;
  15. std::string type;
  16. };
  17. std::vector<_entity> _content;
  18. public:
  19. ModuleSQL();
  20. ~ModuleSQL();
  21. bool configure(const std::string& config) override;
  22. std::string getConfiguration() override;
  23. state update() override;
  24. };
  25. void ModuleSQL::erase_keyword(std::string& str, std::string key) {
  26. while (true) {
  27. int start = (int)str.find(key);
  28. if (start != -1) {
  29. str.erase(start, key.length());
  30. }
  31. else {
  32. return;
  33. }
  34. }
  35. }
  36. ModuleSQL::ModuleSQL()
  37. : ModuleBase(R"JSON(
  38. [{
  39. "name":"database",
  40. "value":""
  41. }])JSON")
  42. {
  43. setType("SQL");
  44. }
  45. state ModuleSQL::update() {
  46. int rc;
  47. std::string sql;
  48. sqlite3_stmt* res;
  49. int step;
  50. // Create SQL statement
  51. sql = "SELECT * "\
  52. "FROM " + _tbname + " "\
  53. "WHERE " + _content[0].key + " = " + std::to_string(getInput(0)->getValue()[0]);
  54. std::cout << sql << std::endl;
  55. // Execute SQL statement
  56. rc = sqlite3_prepare_v2(_db, sql.c_str(), -1, &res, 0);
  57. if (rc != SQLITE_OK) {
  58. fprintf(stderr, "SQL error: %s\n", sqlite3_errmsg(_db));
  59. sqlite3_close(_db);
  60. }
  61. else {
  62. fprintf(stdout, "Operation done successfully\n");
  63. }
  64. step = sqlite3_step(res);
  65. state state = state::UNCHANGED;
  66. if (step == SQLITE_ROW) {
  67. int nCol = sqlite3_column_count(res);
  68. std::string parse_str = "{\"" + _tbname + "\" : {";
  69. for (size_t i = 0; i < nCol; i++)
  70. {
  71. //json val = (char*)sqlite3_column_text(res, i);
  72. getOutput(i)->setValue({ std::atof((char*)sqlite3_column_text(res, i)) });
  73. }
  74. }
  75. sqlite3_finalize(res);
  76. return state;
  77. }
  78. ModuleSQL::~ModuleSQL() {
  79. sqlite3_close(_db);
  80. }
  81. bool ModuleSQL::configure(const std::string& config) {
  82. json config_parsed = json::parse(config);
  83. for (size_t i = 0; i < config_parsed.size(); i++)
  84. {
  85. if (config_parsed[i].contains("name"))
  86. {
  87. if (config_parsed[i]["name"].get<std::string>() == "database")
  88. {
  89. _dbname = config_parsed[i]["value"].get<std::string>();
  90. }
  91. }
  92. }
  93. int rc = sqlite3_open(_dbname.c_str(), &_db);
  94. if (rc) {
  95. fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(_db));
  96. return false;
  97. }
  98. else {
  99. fprintf(stderr, "Opened database successfully\n");
  100. }
  101. std::string sql;
  102. sqlite3_stmt* res;
  103. int step;
  104. // Create SQL statement
  105. sql = "SELECT tbl_name "\
  106. "FROM sqlite_master "\
  107. "WHERE type = 'table' ";
  108. // Execute SQL statement
  109. rc = sqlite3_prepare_v2(_db, sql.c_str(), -1, &res, 0);
  110. if (rc != SQLITE_OK) {
  111. fprintf(stderr, "SQL error: %s\n", sqlite3_errmsg(_db));
  112. sqlite3_close(_db);
  113. }
  114. else {
  115. fprintf(stdout, "Operation done successfully\n");
  116. }
  117. step = sqlite3_step(res);
  118. if (step == SQLITE_ROW) {
  119. int nCol = sqlite3_column_count(res);
  120. for (size_t i = 0; i < nCol; i++)
  121. {
  122. _tbname = (char*)sqlite3_column_text(res, i);
  123. }
  124. }
  125. sqlite3_finalize(res);
  126. // Create SQL statement
  127. sql = "SELECT sql "\
  128. "FROM sqlite_master "\
  129. "WHERE type = 'table' AND tbl_name = '" + _tbname + "'";
  130. //std::cout << sql << std::endl;
  131. // Execute SQL statement
  132. rc = sqlite3_prepare_v2(_db, sql.c_str(), -1, &res, 0);
  133. if (rc != SQLITE_OK) {
  134. fprintf(stderr, "SQL error: %s\n", sqlite3_errmsg(_db));
  135. sqlite3_close(_db);
  136. }
  137. else {
  138. fprintf(stdout, "Operation done successfully\n");
  139. }
  140. step = sqlite3_step(res);
  141. if (step == SQLITE_ROW) {
  142. std::string sql_res = (char*)sqlite3_column_text(res, 0);
  143. int start = sql_res.find("(");
  144. int end = sql_res.find(")");
  145. sql_res = sql_res.substr(++start, (size_t)(--end) - start);
  146. erase_keyword(sql_res, "KEY");
  147. erase_keyword(sql_res, "PRIMARY");
  148. erase_keyword(sql_res, "AUTOINCREMENT");
  149. erase_keyword(sql_res, "NOT NULL");
  150. std::string::iterator new_end = std::unique(sql_res.begin(), sql_res.end(), [](char lhs, char rhs)->bool { return (lhs == rhs) && (lhs == ' '); });
  151. sql_res.erase(new_end, sql_res.end());
  152. _content.clear();
  153. while (true) {
  154. end = sql_res.find(" ,");
  155. if (end == -1)
  156. {
  157. end = sql_res.length();
  158. }
  159. std::string sub_str = sql_res.substr(0, end);
  160. int mid = sub_str.find(" ");
  161. _entity enti;
  162. enti.key = sub_str.substr(0, mid);
  163. enti.type = sub_str.substr(mid + 1, sub_str.length() - (mid + 1));
  164. _content.push_back(enti);
  165. //std::cout << "'" << enti.key << "': '" << enti.type << "'\n";
  166. if (end != sql_res.length())
  167. {
  168. sql_res.erase(0, end + 2);
  169. }
  170. else {
  171. break;
  172. }
  173. }
  174. }
  175. sqlite3_finalize(res);
  176. inputs.push_back(std::make_shared<Input>(this, _content[0].key, inputs.size(), std::vector<double>{0}));
  177. for (auto& cont : _content)
  178. {
  179. outputs.push_back(std::make_shared<Output>(this, cont.key, outputs.size(), std::vector<double>{1}));
  180. }
  181. return true;
  182. }
  183. std::string ModuleSQL::getConfiguration() {
  184. json ret = json::parse(ModuleBase::getConfiguration());
  185. for (size_t i = 0; i < ret.size(); i++)
  186. {
  187. if (ret[i].contains("name"))
  188. {
  189. if (ret[i]["name"].get<std::string>() == "database")
  190. {
  191. ret[i]["value"] = _dbname;
  192. }
  193. }
  194. }
  195. return ret.dump();
  196. }
  197. }