|
@@ -2,33 +2,93 @@
|
|
|
#include <stdio.h>
|
|
|
|
|
|
#include <CLI/CLI.hpp>
|
|
|
+#include <optional>
|
|
|
|
|
|
#include "utils.h"
|
|
|
|
|
|
using json = nlohmann::json;
|
|
|
-using string = std::string;
|
|
|
+using std::nullopt;
|
|
|
+using std::optional;
|
|
|
+using std::string;
|
|
|
+
|
|
|
auto tables = ExistTables("./tables.json");
|
|
|
|
|
|
-void create_table(const std::string& table_name, const TableCols& cols) {
|
|
|
- tables.set(table_name, cols);
|
|
|
+void create_table(const json& j) {
|
|
|
+ auto table_name = table_name_of(j);
|
|
|
+
|
|
|
+ if (tables.exists(table_name)) {
|
|
|
+ throw std::runtime_error(
|
|
|
+ fmt::format("table `{}` exists\n", table_name));
|
|
|
+ }
|
|
|
+ tables.set(table_name, j["cols"]);
|
|
|
tables.save();
|
|
|
}
|
|
|
|
|
|
+optional<TableCol> get_column_define(const string table_name,
|
|
|
+ const json& select_col) {
|
|
|
+ auto type = type_of(select_col);
|
|
|
+ if (type == "identifier") {
|
|
|
+ auto cols = tables[table_name];
|
|
|
+ string colname = select_col["value"];
|
|
|
+ for (auto& col : cols) {
|
|
|
+ if (col.column_name == colname) {
|
|
|
+ return col;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return nullopt;
|
|
|
+ } else if (type == "int" || type == "string" || type == "float") {
|
|
|
+ return TableCol{.column_name = select_col["value"].dump(),
|
|
|
+ .data_type = type,
|
|
|
+ .type = "const",
|
|
|
+ .primary_key = false};
|
|
|
+ } else if (type == "select_all_column") {
|
|
|
+ return TableCol{.column_name = "*",
|
|
|
+ .data_type = "",
|
|
|
+ .type = "select_all_column",
|
|
|
+ .primary_key = false};
|
|
|
+ }
|
|
|
+ return nullopt;
|
|
|
+}
|
|
|
+
|
|
|
+void check_select_table(const json& j) {
|
|
|
+ auto table_name = table_name_of(j);
|
|
|
+ auto select_cols = j["select_cols"];
|
|
|
+
|
|
|
+ for (auto& select_col : select_cols) {
|
|
|
+ if (select_col["type"] == "select_all_column") {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ auto col_def = get_column_define(table_name, select_col["target"]);
|
|
|
+
|
|
|
+ if (!col_def.has_value()) {
|
|
|
+ throw std::runtime_error(
|
|
|
+ fmt::format("column `{}` not exists in `{}`\n",
|
|
|
+ select_col["target"].dump(2), table_name));
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
void process_sql(json& j) {
|
|
|
auto type = j.value("type", "none");
|
|
|
|
|
|
if (type == "create_stmt") {
|
|
|
- auto table_name = j["table_name"];
|
|
|
- if (tables.exists(table_name)) {
|
|
|
- fmt::print("error: table `{}` exists\n", table_name);
|
|
|
+ // 创建表
|
|
|
+ create_table(j);
|
|
|
+ } else {
|
|
|
+ // 其余都会要求表存在
|
|
|
+ auto table_name = table_name_of(j);
|
|
|
+ if (!tables.exists(table_name)) {
|
|
|
+ fmt::print("error: table `{}` does not exist\n", table_name);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (type == "select_stmt") {
|
|
|
+ check_select_table(j);
|
|
|
} else {
|
|
|
- create_table(j["table_name"], j["cols"]);
|
|
|
+ throw std::runtime_error(fmt::format(
|
|
|
+ "Unknown expression type `{}` total: \n{}", type, j.dump(2)));
|
|
|
}
|
|
|
- } else {
|
|
|
- throw std::runtime_error(
|
|
|
- fmt::format("Unknown expression type `{}` total: \n{}", type, j.dump(2)));
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
|
|
|
int main(int argc, char** argv) {
|