utils.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  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. SQLParserRes res;
  14. // auto stdout_name = std::tmpnam(nullptr);
  15. // auto stderr_name = std::tmpnam(nullptr);
  16. auto stdout_name = "/tmp/sql-parser-stdout";
  17. auto stderr_name = "/tmp/sql-parser-stderr";
  18. auto cmd = fmt::format("xmake run sql-parser \"{}\" > {} 2> {}", sql,
  19. stdout_name, stderr_name);
  20. res.exit_code = system(cmd.c_str());
  21. std::ifstream stdout_f(stdout_name);
  22. json stdout_j = json::parse(stdout_f);
  23. res.out = stdout_j;
  24. std::ifstream stderr_f(stderr_name);
  25. res.err.assign((std::istreambuf_iterator<char>(stderr_f)),
  26. (std::istreambuf_iterator<char>()));
  27. return res;
  28. }
  29. ExistTables::ExistTables(const char* file_name) {
  30. table_file_name = file_name;
  31. std::ifstream ifile(table_file_name);
  32. if (!ifile.good()) {
  33. std::ofstream ofile(table_file_name);
  34. ofile << "{}";
  35. ofile.close();
  36. }
  37. ifile.close();
  38. read_from_file();
  39. }
  40. ExistTables* ExistTables::read_from_file() {
  41. std::ifstream f(table_file_name);
  42. json j = json::parse(f);
  43. for (auto& item : j.items()) {
  44. tables[item.key()] = item.value();
  45. }
  46. return this;
  47. };
  48. bool ExistTables::exists(const std::string& table_name) {
  49. return tables.find(table_name) != tables.end();
  50. }
  51. void ExistTables::set(const std::string& table_name, const TableCols& cols) {
  52. tables[table_name] = cols;
  53. }
  54. TableCols ExistTables::operator[](const std::string& table_name) {
  55. return this->get(table_name);
  56. }
  57. TableCols ExistTables::operator[](const std::vector<std::string>& table_names) {
  58. return this->get(table_names);
  59. }
  60. TableCols ExistTables::get(const std::string& table_name) {
  61. return tables[table_name];
  62. }
  63. TableCols ExistTables::get(const std::vector<std::string>& table_names) {
  64. TableCols res = {};
  65. for (let table_name : table_names) {
  66. let cols = this->get(table_name);
  67. res.assign(cols.begin(), cols.end());
  68. }
  69. return res;
  70. }
  71. optional<TableCol> ExistTables::find_col_in_tables(
  72. const std::vector<std::string>& table_names, const std::string col_name) {
  73. for (let table_name : table_names) {
  74. let cols = this->get(table_name);
  75. for (let col : cols) {
  76. if (col.column_name == col_name) {
  77. return col;
  78. }
  79. }
  80. }
  81. return nullopt;
  82. }
  83. void ExistTables::remove(const std::string& table_name) {
  84. tables.erase(table_name);
  85. }
  86. void ExistTables::save() {
  87. json j;
  88. for (auto& item : tables) {
  89. j[item.first] = item.second;
  90. }
  91. std::ofstream f(table_file_name);
  92. f << j.dump(2);
  93. }
  94. optional<TableCol> ExistTables::get_select_column_define(
  95. const vector<string> table_names, const json& select_col) {
  96. auto type = type_of(select_col);
  97. if (type == "identifier") {
  98. return this->find_col_in_tables(table_names, select_col["value"]);
  99. } else if (type == "int" || type == "string" || type == "float") {
  100. return TableCol{.column_name = select_col["value"].dump(),
  101. .type = "const",
  102. .data_type = type,
  103. .primary_key = false};
  104. } else if (type == "select_all_column") {
  105. return TableCol{.column_name = "*",
  106. .type = "select_all_column",
  107. .data_type = "",
  108. .primary_key = false};
  109. } else if (type == "table_field") {
  110. let curr_table_name = select_col["table"];
  111. let curr_field_name = select_col["field"];
  112. if (std::find(table_names.begin(), table_names.end(),
  113. curr_table_name) == table_names.end()) {
  114. return nullopt;
  115. }
  116. return this->find_col_in_tables({curr_table_name}, curr_field_name);
  117. }
  118. return nullopt;
  119. }
  120. string select_column_get_name(const json& j) {
  121. let type = j["type"];
  122. if (type == "identifier") {
  123. return j["value"];
  124. } else if (type == "select_all_column") {
  125. return "select_all_column";
  126. } else if (type == "int" || type == "string" || type == "float") {
  127. return fmt::format("{}:{}", type, j["value"]);
  128. } else if (type == "table_field") {
  129. return fmt::format("{}.{}", j["table"], j["field"]);
  130. }
  131. throw std::runtime_error(
  132. fmt::format("无法将 json 视为 select_column: {}", j.dump(2)));
  133. }