123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- #include "utils.h"
- #include <fmt/core.h>
- #include <algorithm>
- #include <fstream>
- #include <map>
- #include <nlohmann/json.hpp>
- #include <string>
- #include <vector>
- using json = nlohmann::json;
- using std::string;
- using std::vector;
- SQLParserRes parse_sql(const std::string& sql,
- const string& sql_parser_prefix) {
- SQLParserRes res;
- // auto stdout_name = std::tmpnam(nullptr);
- // auto stderr_name = std::tmpnam(nullptr);
- auto stdout_name = "/tmp/sql-parser-stdout";
- auto stderr_name = "/tmp/sql-parser-stderr";
- auto cmd = fmt::format("{} \"{}\" > {} 2> {}", sql_parser_prefix, sql,
- stdout_name, stderr_name);
- res.exit_code = system(cmd.c_str());
- std::ifstream stdout_f(stdout_name);
- json stdout_j = json::parse(stdout_f);
- res.out = stdout_j;
- std::ifstream stderr_f(stderr_name);
- res.err.assign((std::istreambuf_iterator<char>(stderr_f)),
- (std::istreambuf_iterator<char>()));
- return res;
- }
- ExistTables::ExistTables(const char* file_name) {
- table_file_name = file_name;
- std::ifstream ifile(table_file_name);
- if (!ifile.good()) {
- std::ofstream ofile(table_file_name);
- ofile << "{}";
- ofile.close();
- }
- ifile.close();
- read_from_file();
- }
- ExistTables* ExistTables::read_from_file() {
- std::ifstream f(table_file_name);
- json j = json::parse(f);
- for (auto& item : j.items()) {
- tables[item.key()] = item.value();
- }
- return this;
- };
- bool ExistTables::exists(const std::string& table_name) {
- return tables.find(table_name) != tables.end();
- }
- void ExistTables::set(const std::string& table_name, const TableCols& cols) {
- tables[table_name] = cols;
- }
- TableCols ExistTables::operator[](const std::string& table_name) {
- return this->get(table_name);
- }
- TableCols ExistTables::operator[](const std::vector<std::string>& table_names) {
- return this->get(table_names);
- }
- TableCols ExistTables::get(const std::string& table_name) {
- return tables[table_name];
- }
- TableCols ExistTables::get(const std::vector<std::string>& table_names) {
- TableCols res = {};
- for (let table_name : table_names) {
- let cols = this->get(table_name);
- res.assign(cols.begin(), cols.end());
- }
- return res;
- }
- optional<TableCol> ExistTables::find_col_in_tables(
- const std::vector<std::string>& table_names, const std::string col_name) {
- for (let table_name : table_names) {
- let cols = this->get(table_name);
- for (let col : cols) {
- if (col.column_name == col_name) {
- return col;
- }
- }
- }
- return nullopt;
- }
- void ExistTables::remove(const std::string& table_name) {
- tables.erase(table_name);
- }
- void ExistTables::save() {
- json j;
- for (auto& item : tables) {
- j[item.first] = item.second;
- }
- std::ofstream f(table_file_name);
- f << j.dump(2);
- }
- optional<TableCol> ExistTables::get_select_column_define(
- const vector<string> table_names, const json& select_col) {
- auto type = type_of(select_col);
- if (type == "identifier") {
- return this->find_col_in_tables(table_names, select_col["value"]);
- } else if (type == "int" || type == "string" || type == "float") {
- return TableCol{.column_name = select_col["value"].dump(),
- .type = "const",
- .data_type = type,
- .primary_key = false};
- } else if (type == "select_all_column") {
- return TableCol{.column_name = "*",
- .type = "select_all_column",
- .data_type = "",
- .primary_key = false};
- } else if (type == "table_field") {
- let curr_table_name = select_col["table"];
- let curr_field_name = select_col["field"];
- if (std::find(table_names.begin(), table_names.end(),
- curr_table_name) == table_names.end()) {
- return nullopt;
- }
- return this->find_col_in_tables({curr_table_name}, curr_field_name);
- }
- return nullopt;
- }
- string select_column_get_name(const json& j) {
- let type = j["type"];
- if (type == "identifier") {
- return j["value"];
- } else if (type == "select_all_column") {
- return "select_all_column";
- } else if (type == "int" || type == "string" || type == "float") {
- return fmt::format("{}:{}", type, j["value"]);
- } else if (type == "table_field") {
- return fmt::format("{}.{}", j["table"], j["field"]);
- }
- throw std::runtime_error(
- fmt::format("无法将 json 视为 select_column: {}", j.dump(2)));
- }
- bool is_column(const json& j) {
- let type = j.value("type", "none");
- return type == "identifier" || is_const_column(j) ||
- type == "select_all_column" || type == "table_field";
- }
- bool is_const_column(const json& j) {
- let type = j.value("type", "none");
- return type == "int" || type == "string" || type == "float";
- }
- OpType op_type_of(const nlohmann::json& j) {
- // bin_contains_op, bin_logical_op, bin_cmp_op
- if (j.empty()) return OpType::OP_UNKNOWN;
- let type = j.value("op_type", "none");
- if (type == "bin_contains_op") {
- return OpType::OP_CONTAINS;
- } else if (type == "bin_logical_op") {
- return OpType::OP_LOGIC;
- } else if (type == "bin_cmp_op") {
- return OpType::OP_COMPARE;
- }
- return OpType::OP_UNKNOWN;
- }
|