1#include <vkdb/database.h>
2#include <vkdb/interpreter.h>
4#include <vkdb/parser.h>
11 runtime_error_callback runtime_error
13 : name_{
std::move(name)}
14 , callback_{
std::move(error)}
15 , runtime_callback_{
std::move(runtime_error)}
17 , had_runtime_error_{false} {
22 if (table_map_.contains(table_name)) {
23 throw std::runtime_error{
24 "Database::createTable(): Table '" + table_name +
"' already exists."
27 table_map_.emplace(table_name,
Table{
path(), table_name});
28 std::filesystem::create_directories(table_map_.at(table_name).path());
29 return table_map_.at(table_name);
33 if (!table_map_.contains(table_name)) {
34 throw std::runtime_error{
35 "Database::getTable(): Table '" + table_name +
"' does not exist."
38 return table_map_.at(table_name);
42 if (!table_map_.contains(table_name)) {
43 throw std::runtime_error{
44 "Database::dropTable(): Table '" + table_name +
"' does not exist."
47 std::filesystem::remove_all(table_map_.at(table_name).path());
48 table_map_.erase(table_name);
52 std::filesystem::remove_all(
path());
60 return DATABASE_DIRECTORY / name_;
64 auto tables{std::ranges::views::keys(table_map_)};
69 const std::string& source,
73 auto tokens{lexer.tokenize()};
75 Parser parser{tokens, [
this](
Token token,
const std::string& message) {
76 error(token, message);
78 auto expr{parser.parse()};
87 interpreter.
interpret(expr.value(), stream);
93 const std::filesystem::path path,
96 if (path.extension() !=
".vq") {
97 std::cerr <<
"\033[1;32mDatabase::runFile(): File extension cannot be "
98 << path.extension() <<
", must be .vq.\033[0m\n";
101 std::ifstream file{path};
102 if (!file.is_open()) {
103 std::cerr <<
"\033[1;32mDatabase::runFile(): Unable to open file "
104 << path <<
".\033[0m\n";
107 std::stringstream buffer;
108 buffer << file.rdbuf();
109 run(buffer.str(), stream);
115 if (had_runtime_error_) {
123 std::cout <<
"\033[1;31mwelcome to the vq repl! :)\033[0m\n";
124 std::cout <<
"\033[1;31m(on database '" << name_ <<
"')\033[0m\n";
127 std::cout <<
"\033[1;34m(vq) >> \033[0m";
128 if (!std::getline(std::cin, line) || line.empty()) {
137void Database::error(
Token token,
const std::string& message)
noexcept {
138 if (token.type() == TokenType::END_OF_FILE) {
139 report(token.line(),
"at end", message);
141 report(token.line(),
"at '" + token.lexeme() +
"'", message);
146void Database::runtime_error(
const RuntimeError& error)
noexcept {
147 std::cerr <<
"\033[1;32m[line " << error.token().line();
148 std::cerr <<
"] Runtime error: " << error.message() <<
"\033[0m\n";
149 had_runtime_error_ =
true;
152void Database::report(
154 const std::string& where,
155 const std::string& message
157 std::cerr <<
"\033[1;32m[line " << line <<
"] Parse error ";
158 std::cerr << where <<
": " << message <<
"\033[0m\n";
161void Database::load() {
162 const auto db_path{
path()};
163 if (!std::filesystem::exists(db_path)) {
164 std::filesystem::create_directories(db_path);
168 for (
const auto& entry : std::filesystem::directory_iterator(db_path)) {
169 if (entry.is_directory()) {
170 auto table_name{entry.path().filename().string()};
171 table_map_.emplace(table_name, Table{
path(), table_name});
Represents a database in vkdb.
Table & getTable(const TableName &table_name)
Get the Table object.
Database()=delete
Deleted default constructor.
FilePath path() const noexcept
Get the path to the database directory.
std::vector< TableName > tables() const noexcept
Get the names of the tables in the database.
Database & runFile(const std::filesystem::path path, std::ostream &stream=std::cout) noexcept
Run a file.
void clear()
Clear the database.
void dropTable(const TableName &table_name)
Drop the Table object.
Database & runPrompt() noexcept
Run the prompt.
DatabaseName name() const noexcept
Get the name of the database.
Database & run(const std::string &source, std::ostream &stream=std::cout) noexcept
Run a source string.
Table & createTable(const TableName &table_name)
Create a Table object.
void interpret(const Expr &expr, std::ostream &stream=std::cout) const noexcept
Interpret the expression.
Represents a table in vkdb.