Skip to content

Commit

Permalink
Implement an interactive shell
Browse files Browse the repository at this point in the history
  • Loading branch information
fergeben committed Apr 18, 2020
1 parent ab9d4e1 commit 9de89f1
Show file tree
Hide file tree
Showing 17 changed files with 370 additions and 64 deletions.
101 changes: 54 additions & 47 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,46 +8,53 @@ conan_basic_setup()
set(YESS_VERSION_TWEAK "pre-alpha")
configure_file(
src/version.h.in
include/version.h
include/version.h
)

set(CMAKE_CXX_STANDARD 17)

enable_testing()
set(MAIN_FILE src/main.cpp)
set(SRC_FILES
src/server.cpp
src/msg/response.cpp
src/action_handler.cpp
src/db/entities/stream.cpp
src/db/entities/event.cpp
src/db/repositories/stream_repository.cpp
src/db/repositories/sqlite_stream_repo.cpp
src/msg/serializer.cpp
inc_duktape/duktape.c
src/ext/duk_context.cpp
src/grpc_service.cpp
protos/yess.grpc.pb.cc
protos/yess.pb.cc
src/daemonizer.cpp
)
set(MAIN_FILE src/main.cpp src/cmd/shell.cpp src/cmd/shell.hpp src/cmd/shell_commands.cpp src/cmd/shell_commands.hpp)
set(SRC_FILES
src/server.cpp
src/msg/response.cpp
src/action_handler.cpp
src/db/entities/stream.cpp
src/db/entities/event.cpp
src/db/repositories/stream_repository.cpp
src/db/repositories/sqlite_stream_repo.cpp
src/msg/serializer.cpp
inc_duktape/duktape.c
src/ext/duk_context.cpp
src/grpc_service.cpp
protos/yess.grpc.pb.cc
protos/yess.pb.cc
src/daemonizer.cpp
src/cmd/domain_commands.hpp
src/cmd/command.hpp
src/cmd/domain_commands.cpp
src/cmd/command.cpp
src/cmd/command_result.cpp
src/cmd/command_result.hpp
)

set(INC_FILES
src/server.hpp
src/msg/response.hpp
src/action_handler.hpp
src/db/entities/stream.hpp
src/db/entities/event.hpp
src/db/repositories/stream_repository.hpp
src/db/repositories/sqlite_stream_repo.hpp
src/msg/serializer.hpp
src/ext/context.hpp
src/ext/duk_context.hpp
src/log.hpp
src/grpc_service.hpp
protos/yess.grpc.pb.h
protos/yess.pb.h
src/daemonizer.hpp
)
src/server.hpp
src/msg/response.hpp
src/action_handler.hpp
src/db/entities/stream.hpp
src/db/entities/event.hpp
src/db/repositories/stream_repository.hpp
src/db/repositories/sqlite_stream_repo.hpp
src/msg/serializer.hpp
src/ext/context.hpp
src/ext/duk_context.hpp
src/log.hpp
src/grpc_service.hpp
protos/yess.grpc.pb.h
protos/yess.pb.h
src/daemonizer.hpp
)
add_library(${PROJECT_NAME}_objects OBJECT ${SRC_FILES} ${INCL_FILES})
add_subdirectory(utils)
add_subdirectory(debug)
Expand All @@ -68,20 +75,20 @@ message(STATUS "Using gRPC ${gRPC_VERSION}")


target_link_libraries(${PROJECT_NAME} PRIVATE ${CONAN_LIBS} yessutils
gRPC::grpc++
gRPC::grpc++_reflection
protobuf::libprotobuf
-lsystemd
)
gRPC::grpc++
gRPC::grpc++_reflection
protobuf::libprotobuf
-lsystemd
)

add_custom_target(
run
COMMAND ${PROJECT_NAME}
DEPENDS ${PROJECT_NAME}
WORKING_DIRECTORY ${CMAKE_PROJECT_DIR})
run
COMMAND ${PROJECT_NAME}
DEPENDS ${PROJECT_NAME}
WORKING_DIRECTORY ${CMAKE_PROJECT_DIR})

set_target_properties(
${PROJECT_NAME}
PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
${PROJECT_NAME}
PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
4 changes: 2 additions & 2 deletions src/action_handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ Action action_from_str(std::string action)
throw std::runtime_error("Invalid action: " + action);
}

void Action_handler::save_stream(const yess::db::Stream &stream)
void Action_handler::save_stream(const yess::db::Stream &stream) const
{
stream_repo_->create(stream);
}
Expand Down Expand Up @@ -216,7 +216,7 @@ msg::Response Action_handler::handle(const json &obj)
return msg::Response(status, msg);
}

void Action_handler::create_stream(std::string type)
void Action_handler::create_stream(std::string type) const
{
yess::db::Stream stream = {0, type, 0};
save_stream(stream);
Expand Down
4 changes: 2 additions & 2 deletions src/action_handler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ class Action_handler
Action_handler(Action_handler &&handler);
~Action_handler();
msg::Response handle(const json &obj);
void save_stream(const db::Stream &stream);
void save_stream(const db::Stream &stream) const;

void create_stream(std::string type);
void create_stream(std::string type) const;
std::vector<db::Stream> get_all_streams();
// TODO:
// std::vector<db::Stream> get_streams_by_type(std::string type);
Expand Down
6 changes: 6 additions & 0 deletions src/cmd/command.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#include "command.hpp"

// yess::cmd::Command::Command(const Action_handler &handler) :
// handler_(handler)
yess::cmd::Command::Command() {}
yess::cmd::Command::~Command() {}
16 changes: 16 additions & 0 deletions src/cmd/command.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#ifndef YESS_COMMAND_HPP
#define YESS_COMMAND_HPP

#include "command_result.hpp"
namespace yess::cmd
{
class Command
{
public:
Command();
virtual ~Command();
virtual Command_result execute() = 0;
};
} // namespace yess::cmd

#endif // YESS_COMMAND_HPP
14 changes: 14 additions & 0 deletions src/cmd/command_result.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#include "command_result.hpp"
namespace yess::cmd
{
Command_result::Command_result(Status status,
const std::string &msg,
std::any data)
: status_(status), msg_(msg), data_(data)
{
}
std::string Command_result::message() { return msg_; }
Command_result::Status Command_result::status() { return status_; }
std::any Command_result::data() { return data_; }
bool Command_result::ok() { return status_ == Status::ok; }
} // namespace yess::cmd
25 changes: 25 additions & 0 deletions src/cmd/command_result.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#ifndef YESS_COMMAND_RESULT_HPP
#define YESS_COMMAND_RESULT_HPP

#include <any>
#include <string>

namespace yess::cmd
{
class Command_result
{
public:
enum class Status { ok, error, exit };
Command_result(Status status, const std::string &msg, std::any data);
std::string message();
Status status();
std::any data();
bool ok();

private:
Status status_;
std::string msg_;
std::any data_;
};
} // namespace yess::cmd
#endif // YESS_COMMAND_RESULT_HPP
27 changes: 27 additions & 0 deletions src/cmd/domain_commands.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#include "domain_commands.hpp"

using namespace yess::cmd;

Create_stream_req::Create_stream_req(const std::string &type) : type_(type) {}

Create_stream::Create_stream(const Action_handler &handler,
const Create_stream_req &request)
: Domain_command(handler), request_(request)
{
}

Command_result Create_stream::execute()
{
try {
handler_.create_stream(request_.type_);
} catch (std::exception /* ex */) {
std::string msg = "Unexpected error: cannot create stream";
return Command_result(Command_result::Status::error, msg, nullptr);
}
return Command_result(Command_result::Status::ok, "OK", nullptr);
}

Domain_command::Domain_command(const yess::Action_handler &handler)
: handler_(handler)
{
}
35 changes: 35 additions & 0 deletions src/cmd/domain_commands.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#ifndef YESS_DOMAIN_COMMANDS_HPP
#define YESS_DOMAIN_COMMANDS_HPP

#include "command.hpp"
#include "../action_handler.hpp"
#include <string>

namespace yess::cmd
{
class Domain_command : public Command
{
public:
explicit Domain_command(const Action_handler &handler);
protected:
const Action_handler &handler_;


};
struct Create_stream_req
{
explicit Create_stream_req(const std::string& type);
std::string type_;
};

class Create_stream : public Domain_command
{
const Create_stream_req &request_;

public:
Create_stream(const Action_handler& handler, const Create_stream_req& req);
Command_result execute() override;
};
} // namespace yess::cmd

#endif // YESS_DOMAIN_COMMANDS_HPP
84 changes: 84 additions & 0 deletions src/cmd/shell.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
#include "shell.hpp"
// TODO: fix path
#include "../../build/debug/include/version.h"
#include "domain_commands.hpp"
#include "shell_commands.hpp"
#include <sstream>

using namespace yess;

std::unique_ptr<cmd::Command> cmd::Shell::interpret(std::string in)
{
std::tuple<cmd::Shell::Shell_cmd, std::vector<std::string>> cmd_argv =
tokens(in);
auto c = std::get<0>(cmd_argv);
auto argv = std::get<1>(cmd_argv);
switch (c) {
case Shell_cmd::unknown: {
return std::make_unique<cmd::Unknown>();
}
case Shell_cmd::quit: {
return std::make_unique<cmd::Quit>();
}
case Shell_cmd::help: {
return std::make_unique<cmd::Help>();
}
case Shell_cmd::create_stream: {
if (argv.size() != 1) {
// TODO: provide usage hints
return std::make_unique<cmd::Unknown>();
}
auto req = new cmd::Create_stream_req(argv[0]);
return std::make_unique<cmd::Create_stream>(handler_, *req);
}
}
}
cmd::Shell::Shell(const Action_handler &handler) : handler_(handler) {}
void cmd::Shell::execute(const cmd::Command &cmd) {}
void cmd::Shell::run()
{
std::cout << "yess interactive shell (";
std::cout << YESS_VER << ")" << std::endl;
std::cout << std::endl;
std::cout << "Enter 'help' for usage hints." << std::endl;
bool should_exit = false;
while (!should_exit) {
std::cout << prompt_;
std::string line;
std::getline(std::cin, line);
std::unique_ptr<cmd::Command> cmd = interpret(line);
cmd::Command_result result = cmd->execute();
std::cout << result.message() << std::endl;
if (result.status() == Command_result::Status::exit)
should_exit = true;
}
}
std::vector<std::string> to_words(std::string in)
{
std::vector<std::string> result;
std::istringstream ss(in);
do {
std::string word;
ss >> word;
if (!word.empty())
result.push_back(word);
} while (ss);
return result;
}

std::tuple<cmd::Shell::Shell_cmd, std::vector<std::string>>
cmd::Shell::tokens(std::string in)
{
std::vector<std::string> argv = to_words(in);
std::string first = argv[0];
argv.erase(argv.begin());

auto c = cmd::Shell::Shell_cmd::unknown;
if (first == "help")
c = cmd::Shell::Shell_cmd::help;
if (first == "create_stream")
c = cmd::Shell::Shell_cmd::create_stream;
if (first == "quit")
c = cmd::Shell::Shell_cmd::quit;
return std::tuple<Shell_cmd, std::vector<std::string>>(c, argv);
}
30 changes: 30 additions & 0 deletions src/cmd/shell.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#ifndef YESS_SHELL_HPP
#define YESS_SHELL_HPP

#include "../action_handler.hpp"
#include "command.hpp"

namespace yess::cmd
{
class Shell
{
public:
enum class Shell_cmd {
unknown,
help,
create_stream,
quit,
};
Shell(const Action_handler &handler);
void run();

private:
std::tuple<Shell_cmd, std::vector<std::string>> tokens(std::string in);
const Action_handler &handler_;
std::unique_ptr<Command> interpret(std::string in);
void execute(const Command &cmd);
std::string prompt_ = "> ";
};
} // namespace yess::cmd

#endif // YESS_SHELL_HPP
Loading

0 comments on commit 9de89f1

Please sign in to comment.