First version

This commit is contained in:
Yves
2025-02-17 13:07:01 +01:00
parent 4228845a08
commit 75f2880fab
12 changed files with 869 additions and 37 deletions

View File

@@ -0,0 +1,82 @@
#pragma once
#include "duckdb.hpp"
#define CPPHTTPLIB_OPENSSL_SUPPORT
#include "httplib.hpp"
#include <memory>
#include <mutex>
#include <string>
#include <thread>
#include <unordered_map>
namespace httplib = duckdb_httplib_openssl;
namespace duckdb {
class MemoryStream;
namespace ui {
class EventDispatcher {
public:
bool WaitEvent(httplib::DataSink *sink);
void SendEvent(const std::string &message);
void Close();
private:
std::mutex mutex_;
std::condition_variable cv_;
std::atomic_int next_id_ {0};
std::atomic_int current_id_ {-1};
std::atomic_int wait_count_ {0};
std::string message_;
std::atomic_bool closed_ {false};
};
class HttpServer {
public:
static HttpServer* instance();
static bool Started();
static void StopInstance();
bool Start(const uint16_t localPort, const std::string &remoteUrl,
const shared_ptr<DatabaseInstance> &ddbInstance);
bool Stop();
uint16_t LocalPort();
void SendConnectedEvent(const std::string &token);
void SendCatalogChangedEvent();
private:
void SendEvent(const std::string &message);
void Run();
void HandleGetLocalEvents(const httplib::Request &req, httplib::Response &res);
void HandleGetLocalToken(const httplib::Request &req, httplib::Response &res);
void HandleGet(const httplib::Request &req, httplib::Response &res);
void HandleInterrupt(const httplib::Request &req, httplib::Response &res);
void HandleRun(const httplib::Request &req, httplib::Response &res, const httplib::ContentReader &contentReader);
void HandleTokenize(const httplib::Request &req, httplib::Response &res,
const httplib::ContentReader &contentReader);
std::string ReadContent(const httplib::ContentReader &contentReader);
shared_ptr<Connection> FindConnection(const std::string &connectionName);
shared_ptr<Connection> FindOrCreateConnection(const std::string &connectionName);
void SetResponseContent(httplib::Response &res, const MemoryStream &content);
void SetResponseEmptyResult(httplib::Response &res);
void SetResponseErrorResult(httplib::Response &res, const std::string &error);
uint16_t local_port_;
std::string remote_url_;
shared_ptr<DatabaseInstance> ddb_instance_;
std::string user_agent_;
httplib::Server server_;
unique_ptr<std::thread> thread_;
std::mutex connections_mutex_;
std::unordered_map<std::string, shared_ptr<Connection>> connections_;
unique_ptr<EventDispatcher> event_dispatcher_;
static unique_ptr<HttpServer> instance_;
};;
} // namespace ui
} // namespace duckdb

View File

@@ -0,0 +1,9 @@
#pragma once
#include <string>
namespace duckdb {
std::string DecodeBase64(const std::string &str);
} // namespace duckdb

13
src/include/utils/env.hpp Normal file
View File

@@ -0,0 +1,13 @@
#pragma once
#include <string>
namespace duckdb {
const char *TryGetEnv(const char *name);
std::string GetEnvOrDefault(const char *name, const char *default_value);
bool IsEnvEnabled(const char *name);
} // namespace duckdb

View File

@@ -0,0 +1,27 @@
#pragma once
#include <duckdb.hpp>
namespace duckdb {
struct RunOnceTableFunctionState : GlobalTableFunctionState {
RunOnceTableFunctionState() : run(false) {};
std::atomic<bool> run;
static unique_ptr<GlobalTableFunctionState> Init(ClientContext &,
TableFunctionInitInput &) {
return make_uniq<RunOnceTableFunctionState>();
}
};
template <typename T>
T GetSetting(const ClientContext &context, const char *setting_name, const T default_value) {
Value value;
return context.TryGetCurrentSetting(setting_name, value) ? value.GetValue<T>() : default_value;
}
bool ShouldRun(TableFunctionInput &input);
void RegisterTF(DatabaseInstance &instance, const char* name, table_function_t func);
} // namespace duckdb

View File

@@ -0,0 +1,49 @@
#pragma once
#include "duckdb.hpp"
#include <string>
namespace duckdb {
namespace ui {
struct EmptyResult {
void Serialize(duckdb::Serializer &serializer) const;
};
struct TokenizeResult {
duckdb::vector<idx_t> offsets;
duckdb::vector<duckdb::SimplifiedTokenType> types;
void Serialize(duckdb::Serializer &serializer) const;
};
struct ColumnNamesAndTypes {
duckdb::vector<std::string> names;
duckdb::vector<duckdb::LogicalType> types;
void Serialize(duckdb::Serializer &serializer) const;
};
struct Chunk {
uint16_t row_count;
duckdb::vector<duckdb::Vector> vectors;
void Serialize(duckdb::Serializer &serializer) const;
};
struct SuccessResult {
ColumnNamesAndTypes column_names_and_types;
duckdb::vector<Chunk> chunks;
void Serialize(duckdb::Serializer &serializer) const;
};
struct ErrorResult {
std::string error;
void Serialize(duckdb::Serializer &serializer) const;
};
} // namespace ui
} // namespace duckdb