utils.cpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. #include "utils.h"
  2. #include <fmt/core.h>
  3. #include <algorithm>
  4. #include <fstream>
  5. #include <map>
  6. #include <nlohmann/json.hpp>
  7. #include <string>
  8. #include <vector>
  9. using json = nlohmann::json;
  10. using std::string;
  11. using std::vector;
  12. SQLParserRes parse_sql(const std::string& sql,
  13. const string& sql_parser_prefix) {
  14. SQLParserRes res;
  15. // auto stdout_name = std::tmpnam(nullptr);
  16. // auto stderr_name = std::tmpnam(nullptr);
  17. auto stdout_name = "/tmp/sql-parser-stdout";
  18. auto stderr_name = "/tmp/sql-parser-stderr";
  19. auto cmd = fmt::format("{} \"{}\" > {} 2> {}", sql_parser_prefix, sql,
  20. stdout_name, stderr_name);
  21. res.exit_code = system(cmd.c_str());
  22. std::ifstream stdout_f(stdout_name);
  23. json stdout_j = json::parse(stdout_f);
  24. res.out = stdout_j;
  25. std::ifstream stderr_f(stderr_name);
  26. res.err.assign((std::istreambuf_iterator<char>(stderr_f)),
  27. (std::istreambuf_iterator<char>()));
  28. return res;
  29. }
  30. ExistTables::ExistTables(const char* file_name) {
  31. table_file_name = file_name;
  32. std::ifstream ifile(table_file_name);
  33. if (!ifile.good()) {
  34. std::ofstream ofile(table_file_name);
  35. ofile << "{}";
  36. ofile.close();
  37. }
  38. ifile.close();
  39. read_from_file();
  40. }
  41. ExistTables* ExistTables::read_from_file() {
  42. std::ifstream f(table_file_name);
  43. json j = json::parse(f);
  44. for (auto& item : j.items()) {
  45. tables[item.key()] = item.value();
  46. }
  47. return this;
  48. };
  49. bool ExistTables::exists(const std::string& table_name) {
  50. return tables.find(table_name) != tables.end();
  51. }
  52. void ExistTables::set(const std::string& table_name, const TableCols& cols) {
  53. tables[table_name] = cols;
  54. }
  55. TableCols ExistTables::operator[](const std::string& table_name) {
  56. return this->get(table_name);
  57. }
  58. TableCols ExistTables::operator[](const std::vector<std::string>& table_names) {
  59. return this->get(table_names);
  60. }
  61. TableCols ExistTables::get(const std::string& table_name) {
  62. return tables[table_name];
  63. }
  64. TableCols ExistTables::get(const std::vector<std::string>& table_names) {
  65. TableCols res = {};
  66. for (let table_name : table_names) {
  67. let cols = this->get(table_name);
  68. res.assign(cols.begin(), cols.end());
  69. }
  70. return res;
  71. }
  72. optional<TableCol> ExistTables::find_col_in_tables(
  73. const std::vector<std::string>& table_names, const std::string col_name) {
  74. for (let table_name : table_names) {
  75. let cols = this->get(table_name);
  76. for (let col : cols) {
  77. if (col.column_name == col_name) {
  78. return col;
  79. }
  80. }
  81. }
  82. return nullopt;
  83. }
  84. void ExistTables::remove(const std::string& table_name) {
  85. tables.erase(table_name);
  86. }
  87. void ExistTables::save() {
  88. json j;
  89. for (auto& item : tables) {
  90. j[item.first] = item.second;
  91. }
  92. std::ofstream f(table_file_name);
  93. f << j.dump(2);
  94. }
  95. optional<TableCol> ExistTables::get_select_column_define(
  96. const vector<string> table_names, const json& select_col) {
  97. auto type = type_of(select_col);
  98. if (type == "identifier") {
  99. return this->find_col_in_tables(table_names, select_col["value"]);
  100. } else if (type == "int" || type == "string" || type == "float") {
  101. return TableCol{.column_name = select_col["value"].dump(),
  102. .type = "const",
  103. .data_type = type,
  104. .primary_key = false};
  105. } else if (type == "select_all_column") {
  106. return TableCol{.column_name = "*",
  107. .type = "select_all_column",
  108. .data_type = "",
  109. .primary_key = false};
  110. } else if (type == "table_field") {
  111. let curr_table_name = select_col["table"];
  112. let curr_field_name = select_col["field"];
  113. if (std::find(table_names.begin(), table_names.end(),
  114. curr_table_name) == table_names.end()) {
  115. return nullopt;
  116. }
  117. return this->find_col_in_tables({curr_table_name}, curr_field_name);
  118. }
  119. return nullopt;
  120. }
  121. string select_column_get_name(const json& j) {
  122. let type = j["type"];
  123. if (type == "identifier") {
  124. return j["value"];
  125. } else if (type == "select_all_column") {
  126. return "select_all_column";
  127. } else if (type == "int" || type == "string" || type == "float") {
  128. return fmt::format("{}:{}", type, j["value"]);
  129. } else if (type == "table_field") {
  130. return fmt::format("{}.{}", j["table"], j["field"]);
  131. }
  132. throw std::runtime_error(
  133. fmt::format("无法将 json 视为 select_column: {}", j.dump(2)));
  134. }
  135. bool is_column(const json& j) {
  136. let type = j.value("type", "none");
  137. return type == "identifier" || is_const_column(j) ||
  138. type == "select_all_column" || type == "table_field";
  139. }
  140. bool is_const_column(const json& j) {
  141. let type = j.value("type", "none");
  142. return type == "int" || type == "string" || type == "float";
  143. }
  144. OpType op_type_of(const nlohmann::json& j) {
  145. // bin_contains_op, bin_logical_op, bin_cmp_op
  146. if (j.empty()) return OpType::OP_UNKNOWN;
  147. let type = j.value("op_type", "none");
  148. if (type == "bin_contains_op") {
  149. return OpType::OP_CONTAINS;
  150. } else if (type == "bin_logical_op") {
  151. return OpType::OP_LOGIC;
  152. } else if (type == "bin_cmp_op") {
  153. return OpType::OP_COMPARE;
  154. }
  155. return OpType::OP_UNKNOWN;
  156. }