#include "parser.h" #include "usql.h" #include "linenoise.h" // https://dev.to/joaoh82/what-would-sqlite-look-like-if-written-in-rust-part-1-2np4 using namespace std::chrono; const std::vector 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 start_time = high_resolution_clock::now(); auto result = uSql.execute(input); time_point end_time = high_resolution_clock::now(); std::cout << input << std::endl; std::cout << "run time: " << duration_cast(end_time - start_time).count() << " ms " << std::endl <print(); code += input + "\n"; } catch (std::exception &e) { std::cerr << e.what() << std::endl; } } } close_linenoise(); } void debug() { std::vector sql_commands { "set 'DATE_FORMAT' = '%Y-%m-%d' ", "create table history_earnings_dates (datetime date, symbol varchar(8), time varchar(18), title varchar(256))", "insert into history_earnings_dates (symbol,time,datetime,title) values ('BABA', '07:00:00', '2021-11-04', 'Alibaba Group Holding')", "insert into history_earnings_dates (symbol,time,datetime,title) values ('BABA', '07:00:00', '2021-11-04', 'Alibaba Group Holding')", "delete from history_earnings_dates where symbol='BABA' and datetime=to_date('2021-11-04', '%Y-%m-%d')", "select * from history_earnings_dates" }; usql::USql uSql{}; for (const auto &command : sql_commands) { time_point start_time = high_resolution_clock::now(); auto result = uSql.execute(command); time_point end_time = high_resolution_clock::now(); std::cout << command << std::endl; std::cout << "run time: " << duration_cast(end_time - start_time).count() << " ms " << std::endl << std::endl; result->print(); } std::cout << std::endl << std::endl; } int main(int argc, char *argv[]) { #ifdef NDEBUG repl(); #else debug(); #endif return 0; }