usql/main.cpp

158 lines
3.4 KiB
C++

#include "parser.h"
#include "usql.h"
#include "linenoise.h"
#include "debug.h"
using namespace std::chrono;
const std::vector<std::string> commands {
"select", "create", "load", "table"
};
std::string get_history_file_dir() {
std::string file{"/.usql_history.txt"};
const char *t = std::getenv("HOME");
if (t == nullptr) return "/tmp/" + file;
else return std::string{t} + "/" + file;
}
size_t last_token_index( std::string str ) {
// remove trailing white space
while( !str.empty() && std::isspace( str.back() ) ) str.pop_back() ;
// locate the last white space
return str.find_last_of( "() \t\n" ) ;
}
void completion(const char *buf, linenoiseCompletions *lc) {
if (buf != nullptr) {
std::string str{buf};
const auto pos = last_token_index(str);
if (pos == std::string::npos)
return; // cannot find what to complete
std::string token = str.substr(pos + 1);
std::string begining = str.substr(0, pos + 1);
for (const auto & command : commands) {
if (command.find(token) == 0) {
std::string completion_string = begining + command;
linenoiseAddCompletion(lc, completion_string.c_str());
}
}
}
}
char *hints(const char *buf, int *color, int *bold) {
// if (!strcasecmp(buf,"hello")) {
// *color = 35;
// *bold = 0;
// return " World";
// }
return nullptr;
}
void setup_linenoise() {
std::string history_file = get_history_file_dir();
linenoiseHistorySetMaxLen(500);
linenoiseSetCompletionCallback(completion);
linenoiseSetHintsCallback(hints);
linenoiseSetMultiLine(1);
linenoiseHistoryLoad(history_file.c_str());
}
void linenoise_line_read(char *line) {
linenoiseHistoryAdd(line);
}
void close_linenoise() {
std::string history_file = get_history_file_dir();
linenoiseHistorySave(history_file.c_str());
}
void repl() {
std::string code;
std::string input;
setup_linenoise();
usql::USql uSql{};
while (true) {
char *line = linenoise(">>> ");
if (line == nullptr) break;
linenoise_line_read(line);
input = std::string(line);
if (input == "!quit" || input == "!q")
break;
else if (input == "!export" || input == "!x") {
std::cout << "File to export to: ";
std::getline(std::cin, input);
//write_file_contents(input, code);
} else if (!input.empty()) {
try {
time_point<high_resolution_clock> start_time = high_resolution_clock::now();
auto result = uSql.execute(input);
time_point<high_resolution_clock> end_time = high_resolution_clock::now();
std::cout << input << std::endl;
std::cout << "run time: " << duration_cast<milliseconds>(end_time - start_time).count() << " ms " << std::endl <<std::endl;
result->print();
code += input + "\n";
} catch (const std::exception &e) {
std::cerr << e.what() << std::endl;
}
}
}
close_linenoise();
}
void debug() {
usql::USql uSql{};
for (const auto &command : k_debug_sql_commands) {
time_point<high_resolution_clock> start_time = high_resolution_clock::now();
auto result = uSql.execute(command);
time_point<high_resolution_clock> end_time = high_resolution_clock::now();
std::cout << command << std::endl;
std::cout << "run time: " << duration_cast<milliseconds>(end_time - start_time).count() << " ms "
<< std::endl << std::endl;
result->print();
}
std::cout << std::endl << std::endl;
}
int main(int argc, char *argv[]) {
if (argc == 2 && strcpy(argv[1], "-debug")) {
debug();
} else {
repl();
}
return 0;
}