begining of usql command line tool

This commit is contained in:
2021-08-04 23:09:45 +02:00
parent 50a7993a2e
commit 805ea58bd9
6 changed files with 1457 additions and 2 deletions

1
.gitignore vendored
View File

@@ -1,3 +1,4 @@
build
cmake-build-debug
.DS_Store
tmp/.idea

14
.vscode/settings.json vendored
View File

@@ -76,5 +76,17 @@
},
"C_Cpp.intelliSenseEngineFallback": "Disabled",
"cmake.configureOnOpen": true,
"C_Cpp.configurationWarnings": "Disabled"
"C_Cpp.configurationWarnings": "Disabled",
"sqltools.connections": [
{
"previewLimit": 50,
"server": "localhost",
"port": 5432,
"driver": "PostgreSQL",
"name": "localhost",
"database": "sf",
"username": "vaclavt",
"password": "vaclavtpasswd"
}
]
}

View File

@@ -14,7 +14,7 @@ set(PROJECT_NAME usql)
include_directories(${CMAKE_SOURCE_DIR}/clib ${CMAKE_SOURCE_DIR})
set(SOURCE
exception.cpp lexer.cpp parser.cpp usql.cpp main.cpp table.cpp table.h row.cpp row.h csvreader.cpp csvreader.h ml_date.cpp clib/ml_string.cpp)
exception.cpp lexer.cpp parser.cpp usql.cpp main.cpp table.cpp table.h row.cpp row.h csvreader.cpp csvreader.h ml_date.cpp clib/ml_string.cpp clib/linenoise.c)
add_executable(${PROJECT_NAME} ${SOURCE})

1242
clib/linenoise.c Normal file

File diff suppressed because it is too large Load Diff

77
clib/linenoise.h Normal file
View File

@@ -0,0 +1,77 @@
/* linenoise.h -- VERSION 1.0
*
* Guerrilla line editing library against the idea that a line editing lib
* needs to be 20,000 lines of C code.
*
* See linenoise.c for more information.
*
* ------------------------------------------------------------------------
*
* Copyright (c) 2010-2014, Salvatore Sanfilippo <antirez at gmail dot com>
* Copyright (c) 2010-2013, Pieter Noordhuis <pcnoordhuis at gmail dot com>
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __LINENOISE_H
#define __LINENOISE_H
#ifdef __cplusplus
extern "C" {
#endif
#include "stddef.h"
typedef struct linenoiseCompletions {
size_t len;
char **cvec;
} linenoiseCompletions;
typedef void(linenoiseCompletionCallback)(const char *, linenoiseCompletions *);
typedef char*(linenoiseHintsCallback)(const char *, int *color, int *bold);
typedef void(linenoiseFreeHintsCallback)(void *);
void linenoiseSetCompletionCallback(linenoiseCompletionCallback *);
void linenoiseSetHintsCallback(linenoiseHintsCallback *);
void linenoiseSetFreeHintsCallback(linenoiseFreeHintsCallback *);
void linenoiseAddCompletion(linenoiseCompletions *, const char *);
char *linenoise(const char *prompt);
void linenoiseFree(void *ptr);
int linenoiseHistoryAdd(const char *line);
int linenoiseHistorySetMaxLen(int len);
int linenoiseHistorySave(const char *filename);
int linenoiseHistoryLoad(const char *filename);
void linenoiseClearScreen(void);
void linenoiseSetMultiLine(int ml);
void linenoisePrintKeyCodes(void);
void linenoiseMaskModeEnable(void);
void linenoiseMaskModeDisable(void);
#ifdef __cplusplus
}
#endif
#endif /* __LINENOISE_H */

123
main.cpp
View File

@@ -1,10 +1,129 @@
#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<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 (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<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 (std::exception &e) {
std::cerr << e.what() << std::endl;
}
}
}
close_linenoise();
}
int main(int argc, char *argv[]) {
std::vector<std::string> sql_commands{
"create table a (i integer not null, s varchar(64), f float null)",
@@ -58,5 +177,9 @@ int main(int argc, char *argv[]) {
result->print();
}
std::cout << std::endl << std::endl;
repl();
return 0;
}