#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 (auto t = commands.begin(); t != commands.end(); ++t) { if(t->find(token) == 0) { std::string completion_string = begining + *t; 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 != "") { 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(); } int main(int argc, char *argv[]) { std::vector sql_commands{ "create table a (i integer not null, s varchar(64), f float null)", "insert into a (i, s) values(1, upper('one'))", // "update table a set s = 'null string aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'", // "update table a set i = null", "insert into a (i, s) values(2, 'two')", "insert into a (i, s) values(3, 'two')", "insert into a (i, s) values(4, lower('FOUR'))", "insert into a (i, s) values(5, 'five')", "insert into a (i, s) values(to_date('20.12.1973', '%d.%m.%Y'), 'six')", "save table a into '/tmp/a.csv'", "select i, s from a where i > 2 order by 1 desc offset 1 limit 1", "select distinct s from a", // "select i, s from a where i = 1", // "select i, s from a where s = 'two'", // "select i, s from a where i <= 3 and s = 'one'", // "select i, s from a where i > 0", "delete from a where i = 4", // "select i, s from a where i > 0", // "update a set f = 9.99 where i = 3", // "select i, s, f from a where i = 3", // "update a set s = 'three', f = f + 0.01 where i = 3", // "select i, s, f from a where i = 3", // "create table data (ticker varchar(8), price float null)", // "load data from '/Users/vaclavt/Library/Mobile Documents/com~apple~CloudDocs/Development/usql/data.csv')", // "select ticker, price from data", // "select i, s, f from a where i < 300", // "create table x as select i, s, f from a where i < 300", // "select i, s, f from x where i < 300", // "drop table x", // "select i, s, f from a where i > 300", // "select i, to_string(i, '%d.%m.%Y'), s, f from a where i > 300", "create table prices (datetime integer, symbol varchar(8), prev_close float, open float, price float, change float, change_prct varchar(16))", "load prices from '/Users/vaclavt/Library/Mobile Documents/com~apple~CloudDocs/Development/usql/prices.csv'", // "insert into prices (datetime, symbol, prev_close, open, price, change, change_prct) values (1626979443, 'MPC', 54.08, 53.82, 53.63, -0.832101, '-0.83 %')", "select to_string(datetime, '%d.%m.%Y %H:%M:%S'), symbol, prev_close, open, price, change, change_prct, datetime from prices where symbol = 'SYF' order by 8 desc limit 10" }; usql::USql uSql{}; for (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 <print(); } std::cout << std::endl << std::endl; repl(); return 0; }