Compare commits
27 Commits
yl/debug-c
...
yl/format-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
539762231b | ||
|
|
32fcf7e620 | ||
|
|
ccaf92e99d | ||
|
|
22721d7edd | ||
|
|
e06cd347fb | ||
|
|
fb016137ee | ||
|
|
ab5f005bce | ||
|
|
9c05c83412 | ||
|
|
c63b39fb62 | ||
|
|
0d72926508 | ||
|
|
bffad99acc | ||
|
|
c7d73dcb8d | ||
|
|
6145a1b4a9 | ||
|
|
17be068d61 | ||
|
|
c9d93eee2e | ||
|
|
763e521a99 | ||
|
|
875fa2161c | ||
|
|
fda5caf296 | ||
|
|
183422172c | ||
|
|
c6f57c2f9c | ||
|
|
6cbef80577 | ||
|
|
277b48c4c9 | ||
|
|
ec5334099f | ||
|
|
37c738af28 | ||
|
|
07ed1ea806 | ||
|
|
8f35729d11 | ||
|
|
2715fb15c1 |
40
.github/workflows/MainDistributionPipeline.yml
vendored
40
.github/workflows/MainDistributionPipeline.yml
vendored
@@ -3,8 +3,14 @@
|
|||||||
#
|
#
|
||||||
name: Main Extension Distribution Pipeline
|
name: Main Extension Distribution Pipeline
|
||||||
on:
|
on:
|
||||||
push:
|
|
||||||
pull_request:
|
pull_request:
|
||||||
|
paths-ignore:
|
||||||
|
- "ts/**"
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- "main"
|
||||||
|
paths-ignore:
|
||||||
|
- "ts/**"
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
@@ -23,31 +29,43 @@ jobs:
|
|||||||
|
|
||||||
duckdb-next-patch-build:
|
duckdb-next-patch-build:
|
||||||
name: Build next patch extension binaries
|
name: Build next patch extension binaries
|
||||||
uses: duckdb/extension-ci-tools/.github/workflows/_extension_distribution.yml@v1.2.1
|
uses: duckdb/extension-ci-tools/.github/workflows/_extension_distribution.yml@v1.3.0
|
||||||
with:
|
with:
|
||||||
ci_tools_version: v1.2.1
|
ci_tools_version: v1.3.0
|
||||||
duckdb_version: v1.2-histrionicus
|
duckdb_version: v1.3-ossivalis
|
||||||
exclude_archs: 'wasm_mvp;wasm_eh;wasm_threads'
|
exclude_archs: 'wasm_mvp;wasm_eh;wasm_threads'
|
||||||
extension_name: ui
|
extension_name: ui
|
||||||
|
|
||||||
duckdb-stable-build:
|
duckdb-stable-build:
|
||||||
name: Build stable extension binaries
|
name: Build stable extension binaries
|
||||||
uses: duckdb/extension-ci-tools/.github/workflows/_extension_distribution.yml@v1.2.1
|
uses: duckdb/extension-ci-tools/.github/workflows/_extension_distribution.yml@v1.3.0
|
||||||
with:
|
with:
|
||||||
ci_tools_version: v1.2.1
|
ci_tools_version: v1.3.0
|
||||||
duckdb_version: v1.2.1
|
duckdb_version: v1.3.0
|
||||||
exclude_archs: 'wasm_mvp;wasm_eh;wasm_threads'
|
exclude_archs: 'wasm_mvp;wasm_eh;wasm_threads'
|
||||||
extension_name: ui
|
extension_name: ui
|
||||||
|
|
||||||
duckdb-stable-deploy:
|
duckdb-stable-deploy:
|
||||||
if: ${{ startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main' }}
|
if: ${{ github.repository == 'duckdb/duckdb-ui' && ( startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main' ) }}
|
||||||
name: Deploy stable extension binaries
|
name: Deploy stable extension binaries
|
||||||
needs: duckdb-stable-build
|
needs: duckdb-stable-build
|
||||||
uses: duckdb/extension-ci-tools/.github/workflows/_extension_deploy.yml@v1.2.1
|
uses: duckdb/extension-ci-tools/.github/workflows/_extension_deploy.yml@v1.3.0
|
||||||
secrets: inherit
|
secrets: inherit
|
||||||
with:
|
with:
|
||||||
extension_name: ui
|
extension_name: ui
|
||||||
duckdb_version: v1.2.1
|
ci_tools_version: v1.3.0
|
||||||
ci_tools_version: v1.2.1
|
duckdb_version: v1.3.0
|
||||||
exclude_archs: 'wasm_mvp;wasm_eh;wasm_threads'
|
exclude_archs: 'wasm_mvp;wasm_eh;wasm_threads'
|
||||||
deploy_latest: ${{ startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main' }}
|
deploy_latest: ${{ startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main' }}
|
||||||
|
|
||||||
|
format-check:
|
||||||
|
name: Check formatting
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: 'recursive'
|
||||||
|
|
||||||
|
- name: Check formatting
|
||||||
|
run: make format-check
|
||||||
2
.gitmodules
vendored
2
.gitmodules
vendored
@@ -1,7 +1,7 @@
|
|||||||
[submodule "duckdb"]
|
[submodule "duckdb"]
|
||||||
path = duckdb
|
path = duckdb
|
||||||
url = https://github.com/duckdb/duckdb
|
url = https://github.com/duckdb/duckdb
|
||||||
branch = v1.2.1
|
branch = v1.3.0
|
||||||
[submodule "extension-ci-tools"]
|
[submodule "extension-ci-tools"]
|
||||||
path = extension-ci-tools
|
path = extension-ci-tools
|
||||||
url = https://github.com/duckdb/extension-ci-tools
|
url = https://github.com/duckdb/extension-ci-tools
|
||||||
|
|||||||
2
duckdb
2
duckdb
Submodule duckdb updated: 8e52ec4395...71c5c07cdd
Submodule extension-ci-tools updated: 00e6af0684...b3a2f0d29e
@@ -9,6 +9,7 @@
|
|||||||
#include "utils/serialization.hpp"
|
#include "utils/serialization.hpp"
|
||||||
#include "version.hpp"
|
#include "version.hpp"
|
||||||
#include "watcher.hpp"
|
#include "watcher.hpp"
|
||||||
|
#include <duckdb/common/http_util.hpp>
|
||||||
#include <duckdb/common/serializer/binary_serializer.hpp>
|
#include <duckdb/common/serializer/binary_serializer.hpp>
|
||||||
#include <duckdb/common/serializer/memory_stream.hpp>
|
#include <duckdb/common/serializer/memory_stream.hpp>
|
||||||
#include <duckdb/main/attached_database.hpp>
|
#include <duckdb/main/attached_database.hpp>
|
||||||
@@ -94,13 +95,17 @@ const HttpServer &HttpServer::Start(ClientContext &context, bool *was_started) {
|
|||||||
|
|
||||||
const auto remote_url = GetRemoteUrl(context);
|
const auto remote_url = GetRemoteUrl(context);
|
||||||
const auto port = GetLocalPort(context);
|
const auto port = GetLocalPort(context);
|
||||||
|
auto &http_util = HTTPUtil::Get(*context.db);
|
||||||
|
// FIXME - https://github.com/duckdb/duckdb/pull/17655 will remove `unused`
|
||||||
|
auto http_params = http_util.InitializeParameters(context, "unused");
|
||||||
auto server = GetInstance(context);
|
auto server = GetInstance(context);
|
||||||
server->DoStart(port, remote_url);
|
server->DoStart(port, remote_url, std::move(http_params));
|
||||||
return *server;
|
return *server;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HttpServer::DoStart(const uint16_t _local_port,
|
void HttpServer::DoStart(const uint16_t _local_port,
|
||||||
const std::string &_remote_url) {
|
const std::string &_remote_url,
|
||||||
|
unique_ptr<HTTPParams> _http_params) {
|
||||||
if (Started()) {
|
if (Started()) {
|
||||||
throw std::runtime_error("HttpServer already started");
|
throw std::runtime_error("HttpServer already started");
|
||||||
}
|
}
|
||||||
@@ -108,6 +113,7 @@ void HttpServer::DoStart(const uint16_t _local_port,
|
|||||||
local_port = _local_port;
|
local_port = _local_port;
|
||||||
local_url = StringUtil::Format("http://localhost:%d", local_port);
|
local_url = StringUtil::Format("http://localhost:%d", local_port);
|
||||||
remote_url = _remote_url;
|
remote_url = _remote_url;
|
||||||
|
http_params = std::move(_http_params);
|
||||||
user_agent =
|
user_agent =
|
||||||
StringUtil::Format("duckdb-ui/%s-%s(%s)", DuckDB::LibraryVersion(),
|
StringUtil::Format("duckdb-ui/%s-%s(%s)", DuckDB::LibraryVersion(),
|
||||||
UI_EXTENSION_VERSION, DuckDB::Platform());
|
UI_EXTENSION_VERSION, DuckDB::Platform());
|
||||||
@@ -144,6 +150,7 @@ void HttpServer::DoStop() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ddb_instance.reset();
|
ddb_instance.reset();
|
||||||
|
http_params = nullptr;
|
||||||
remote_url = "";
|
remote_url = "";
|
||||||
local_port = 0;
|
local_port = 0;
|
||||||
}
|
}
|
||||||
@@ -240,19 +247,47 @@ void HttpServer::HandleGetLocalToken(const httplib::Request &req,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Adapted from
|
||||||
|
// https://github.com/duckdb/duckdb/blob/1f8b6839ea7864c3e3fb020574f67384cb58124c/src/main/http/http_util.cpp#L129-L147
|
||||||
|
// Which is not currently exposed.
|
||||||
|
void HttpServer::InitClientFromParams(httplib::Client &client) {
|
||||||
|
auto sec = static_cast<time_t>(http_params->timeout);
|
||||||
|
auto usec = static_cast<time_t>(http_params->timeout_usec);
|
||||||
|
client.set_keep_alive(true);
|
||||||
|
client.set_write_timeout(sec, usec);
|
||||||
|
client.set_read_timeout(sec, usec);
|
||||||
|
client.set_connection_timeout(sec, usec);
|
||||||
|
|
||||||
|
if (!http_params->http_proxy.empty()) {
|
||||||
|
client.set_proxy(http_params->http_proxy,
|
||||||
|
static_cast<int>(http_params->http_proxy_port));
|
||||||
|
|
||||||
|
if (!http_params->http_proxy_username.empty()) {
|
||||||
|
client.set_proxy_basic_auth(http_params->http_proxy_username,
|
||||||
|
http_params->http_proxy_password);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void HttpServer::HandleGet(const httplib::Request &req,
|
void HttpServer::HandleGet(const httplib::Request &req,
|
||||||
httplib::Response &res) {
|
httplib::Response &res) {
|
||||||
// Create HTTP client to remote URL
|
// Create HTTP client to remote URL
|
||||||
// TODO: Can this be created once and shared?
|
// TODO: Can this be created once and shared?
|
||||||
httplib::Client client(remote_url);
|
httplib::Client client(remote_url);
|
||||||
client.set_keep_alive(true);
|
InitClientFromParams(client);
|
||||||
|
|
||||||
if (IsEnvEnabled("ui_disable_server_certificate_verification")) {
|
if (IsEnvEnabled("ui_disable_server_certificate_verification")) {
|
||||||
client.enable_server_certificate_verification(false);
|
client.enable_server_certificate_verification(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
httplib::Headers headers = {{"User-Agent", user_agent}};
|
||||||
|
auto cookie = req.get_header_value("Cookie");
|
||||||
|
if (!cookie.empty()) {
|
||||||
|
headers.emplace("Cookie", cookie);
|
||||||
|
}
|
||||||
|
|
||||||
// forward GET to remote URL
|
// forward GET to remote URL
|
||||||
auto result = client.Get(req.path, req.params, {{"User-Agent", user_agent}});
|
auto result = client.Get(req.path, req.params, headers);
|
||||||
if (!result) {
|
if (!result) {
|
||||||
res.status = 500;
|
res.status = 500;
|
||||||
res.set_content("Could not fetch: '" + req.path + "' from '" + remote_url +
|
res.set_content("Could not fetch: '" + req.path + "' from '" + remote_url +
|
||||||
@@ -366,13 +401,63 @@ void HttpServer::DoHandleRun(const httplib::Request &req,
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unique_ptr<SQLStatement> last_statement;
|
||||||
|
|
||||||
|
auto statements = connection->ExtractStatements(content);
|
||||||
|
auto statement_count = statements.size();
|
||||||
|
|
||||||
|
if (statement_count == 0) {
|
||||||
|
SetResponseErrorResult(res, "No statements");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there's more than one statement, run all but the last.
|
||||||
|
if (statement_count > 1) {
|
||||||
|
for (auto i = 0; i < statement_count - 1; ++i) {
|
||||||
|
auto pending = connection->PendingQuery(std::move(statements[i]));
|
||||||
|
// Return any error found before execution.
|
||||||
|
if (pending->HasError()) {
|
||||||
|
SetResponseErrorResult(res, pending->GetError());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Execute tasks until result is ready (or there's an error).
|
||||||
|
auto exec_result = PendingExecutionResult::RESULT_NOT_READY;
|
||||||
|
while (!PendingQueryResult::IsResultReady(exec_result)) {
|
||||||
|
exec_result = pending->ExecuteTask();
|
||||||
|
if (exec_result == PendingExecutionResult::BLOCKED ||
|
||||||
|
exec_result == PendingExecutionResult::NO_TASKS_AVAILABLE) {
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Return any error found during execution.
|
||||||
|
switch (exec_result) {
|
||||||
|
case PendingExecutionResult::EXECUTION_ERROR:
|
||||||
|
SetResponseErrorResult(res, pending->GetError());
|
||||||
|
return;
|
||||||
|
case PendingExecutionResult::EXECUTION_FINISHED:
|
||||||
|
case PendingExecutionResult::RESULT_READY:
|
||||||
|
// ignore the result
|
||||||
|
pending->Execute();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
SetResponseErrorResult(
|
||||||
|
res, StringUtil::Format("Unexpected PendingExecutionResult: %s",
|
||||||
|
exec_result));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the last statement.
|
||||||
|
auto &statement_to_run = statements[statement_count - 1];
|
||||||
|
|
||||||
// We use a pending query so we can execute tasks and fetch chunks
|
// We use a pending query so we can execute tasks and fetch chunks
|
||||||
// incrementally. This enables cancellation.
|
// incrementally. This enables cancellation.
|
||||||
unique_ptr<PendingQueryResult> pending;
|
unique_ptr<PendingQueryResult> pending;
|
||||||
|
|
||||||
// Create pending query, with request content as SQL.
|
// Create pending query, with request content as SQL.
|
||||||
if (parameter_values.size() > 0) {
|
if (parameter_values.size() > 0) {
|
||||||
auto prepared = connection->Prepare(content);
|
auto prepared = connection->Prepare(std::move(statement_to_run));
|
||||||
if (prepared->HasError()) {
|
if (prepared->HasError()) {
|
||||||
SetResponseErrorResult(res, prepared->GetError());
|
SetResponseErrorResult(res, prepared->GetError());
|
||||||
return;
|
return;
|
||||||
@@ -385,7 +470,7 @@ void HttpServer::DoHandleRun(const httplib::Request &req,
|
|||||||
}
|
}
|
||||||
pending = prepared->PendingQuery(values, true);
|
pending = prepared->PendingQuery(values, true);
|
||||||
} else {
|
} else {
|
||||||
pending = connection->PendingQuery(content, true);
|
pending = connection->PendingQuery(std::move(statement_to_run), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pending->HasError()) {
|
if (pending->HasError()) {
|
||||||
@@ -433,7 +518,9 @@ void HttpServer::DoHandleRun(const httplib::Request &req,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
SetResponseErrorResult(res, "Unexpected PendingExecutionResult");
|
SetResponseErrorResult(
|
||||||
|
res, StringUtil::Format("Unexpected PendingExecutionResult: %s",
|
||||||
|
exec_result));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <duckdb.hpp>
|
#include <duckdb.hpp>
|
||||||
|
#include <duckdb/common/http_util.hpp>
|
||||||
|
|
||||||
#define CPPHTTPLIB_OPENSSL_SUPPORT
|
#define CPPHTTPLIB_OPENSSL_SUPPORT
|
||||||
#include "httplib.hpp"
|
#include "httplib.hpp"
|
||||||
@@ -15,6 +16,7 @@
|
|||||||
namespace httplib = duckdb_httplib_openssl;
|
namespace httplib = duckdb_httplib_openssl;
|
||||||
|
|
||||||
namespace duckdb {
|
namespace duckdb {
|
||||||
|
class HTTPParams;
|
||||||
class MemoryStream;
|
class MemoryStream;
|
||||||
|
|
||||||
namespace ui {
|
namespace ui {
|
||||||
@@ -40,7 +42,8 @@ private:
|
|||||||
friend class Watcher;
|
friend class Watcher;
|
||||||
|
|
||||||
// Lifecycle
|
// Lifecycle
|
||||||
void DoStart(const uint16_t local_port, const std::string &remote_url);
|
void DoStart(const uint16_t local_port, const std::string &remote_url,
|
||||||
|
unique_ptr<HTTPParams>);
|
||||||
void DoStop();
|
void DoStop();
|
||||||
void Run();
|
void Run();
|
||||||
void UpdateDatabaseInstance(shared_ptr<DatabaseInstance> context_db);
|
void UpdateDatabaseInstance(shared_ptr<DatabaseInstance> context_db);
|
||||||
@@ -67,6 +70,7 @@ private:
|
|||||||
|
|
||||||
// Misc
|
// Misc
|
||||||
shared_ptr<DatabaseInstance> LockDatabaseInstance();
|
shared_ptr<DatabaseInstance> LockDatabaseInstance();
|
||||||
|
void InitClientFromParams(httplib::Client &);
|
||||||
|
|
||||||
uint16_t local_port;
|
uint16_t local_port;
|
||||||
std::string local_url;
|
std::string local_url;
|
||||||
@@ -77,6 +81,7 @@ private:
|
|||||||
unique_ptr<std::thread> main_thread;
|
unique_ptr<std::thread> main_thread;
|
||||||
unique_ptr<EventDispatcher> event_dispatcher;
|
unique_ptr<EventDispatcher> event_dispatcher;
|
||||||
unique_ptr<Watcher> watcher;
|
unique_ptr<Watcher> watcher;
|
||||||
|
unique_ptr<HTTPParams> http_params;
|
||||||
|
|
||||||
static unique_ptr<HttpServer> server_instance;
|
static unique_ptr<HttpServer> server_instance;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,7 +6,12 @@ namespace duckdb {
|
|||||||
|
|
||||||
class UiExtension : public Extension {
|
class UiExtension : public Extension {
|
||||||
public:
|
public:
|
||||||
|
#ifdef DUCKDB_CPP_EXTENSION_ENTRY
|
||||||
|
void Load(ExtensionLoader &loader) override;
|
||||||
|
#else
|
||||||
void Load(DuckDB &db) override;
|
void Load(DuckDB &db) override;
|
||||||
|
#endif
|
||||||
|
|
||||||
std::string Name() override;
|
std::string Name() override;
|
||||||
std::string Version() const override;
|
std::string Version() const override;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <duckdb.hpp>
|
#include <duckdb.hpp>
|
||||||
|
#ifndef DUCKDB_CPP_EXTENSION_ENTRY
|
||||||
#include <duckdb/main/extension_util.hpp>
|
#include <duckdb/main/extension_util.hpp>
|
||||||
|
#endif
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
namespace duckdb {
|
namespace duckdb {
|
||||||
@@ -64,6 +66,15 @@ void TableFunc(ClientContext &context, TableFunctionInput &input,
|
|||||||
output.SetValue(0, 0, result);
|
output.SetValue(0, 0, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DUCKDB_CPP_EXTENSION_ENTRY
|
||||||
|
template <typename Func, Func func>
|
||||||
|
void RegisterTF(ExtensionLoader &loader, const char *name) {
|
||||||
|
TableFunction tf(name, {}, internal::TableFunc<Func, func>,
|
||||||
|
internal::SingleStringResultBind,
|
||||||
|
RunOnceTableFunctionState::Init);
|
||||||
|
loader.RegisterFunction(tf);
|
||||||
|
}
|
||||||
|
#else
|
||||||
template <typename Func, Func func>
|
template <typename Func, Func func>
|
||||||
void RegisterTF(DatabaseInstance &instance, const char *name) {
|
void RegisterTF(DatabaseInstance &instance, const char *name) {
|
||||||
TableFunction tf(name, {}, internal::TableFunc<Func, func>,
|
TableFunction tf(name, {}, internal::TableFunc<Func, func>,
|
||||||
@@ -71,10 +82,16 @@ void RegisterTF(DatabaseInstance &instance, const char *name) {
|
|||||||
RunOnceTableFunctionState::Init);
|
RunOnceTableFunctionState::Init);
|
||||||
ExtensionUtil::RegisterFunction(instance, tf);
|
ExtensionUtil::RegisterFunction(instance, tf);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
|
||||||
|
#ifdef DUCKDB_CPP_EXTENSION_ENTRY
|
||||||
|
#define REGISTER_TF(name, func) \
|
||||||
|
internal::RegisterTF<decltype(&func), &func>(loader, name)
|
||||||
|
#else
|
||||||
#define REGISTER_TF(name, func) \
|
#define REGISTER_TF(name, func) \
|
||||||
internal::RegisterTF<decltype(&func), &func>(instance, name)
|
internal::RegisterTF<decltype(&func), &func>(instance, name)
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace duckdb
|
} // namespace duckdb
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#define OPEN_COMMAND "start"
|
#define OPEN_COMMAND "start"
|
||||||
|
#undef CreateDirectory // avoid being transformed to `CreateDirectoryA`
|
||||||
#elif __linux__
|
#elif __linux__
|
||||||
#define OPEN_COMMAND "xdg-open"
|
#define OPEN_COMMAND "xdg-open"
|
||||||
#else
|
#else
|
||||||
@@ -81,7 +82,12 @@ void InitStorageExtension(duckdb::DatabaseInstance &db) {
|
|||||||
config.storage_extensions[STORAGE_EXTENSION_KEY] = std::move(ext);
|
config.storage_extensions[STORAGE_EXTENSION_KEY] = std::move(ext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DUCKDB_CPP_EXTENSION_ENTRY
|
||||||
|
static void LoadInternal(ExtensionLoader &loader) {
|
||||||
|
auto &instance = loader.GetDatabaseInstance();
|
||||||
|
#else
|
||||||
static void LoadInternal(DatabaseInstance &instance) {
|
static void LoadInternal(DatabaseInstance &instance) {
|
||||||
|
#endif
|
||||||
InitStorageExtension(instance);
|
InitStorageExtension(instance);
|
||||||
|
|
||||||
// If the server is already running we need to update the database instance
|
// If the server is already running we need to update the database instance
|
||||||
@@ -128,11 +134,20 @@ static void LoadInternal(DatabaseInstance &instance) {
|
|||||||
TableFunction tf("ui_is_started", {}, IsUIStartedTableFunc,
|
TableFunction tf("ui_is_started", {}, IsUIStartedTableFunc,
|
||||||
internal::SingleBoolResultBind,
|
internal::SingleBoolResultBind,
|
||||||
RunOnceTableFunctionState::Init);
|
RunOnceTableFunctionState::Init);
|
||||||
|
#ifdef DUCKDB_CPP_EXTENSION_ENTRY
|
||||||
|
loader.RegisterFunction(tf);
|
||||||
|
#else
|
||||||
ExtensionUtil::RegisterFunction(instance, tf);
|
ExtensionUtil::RegisterFunction(instance, tf);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DUCKDB_CPP_EXTENSION_ENTRY
|
||||||
|
void UiExtension::Load(ExtensionLoader &loader) { LoadInternal(loader); }
|
||||||
|
#else
|
||||||
void UiExtension::Load(DuckDB &db) { LoadInternal(*db.instance); }
|
void UiExtension::Load(DuckDB &db) { LoadInternal(*db.instance); }
|
||||||
|
#endif
|
||||||
|
|
||||||
std::string UiExtension::Name() { return "ui"; }
|
std::string UiExtension::Name() { return "ui"; }
|
||||||
|
|
||||||
std::string UiExtension::Version() const { return UI_EXTENSION_VERSION; }
|
std::string UiExtension::Version() const { return UI_EXTENSION_VERSION; }
|
||||||
@@ -141,10 +156,14 @@ std::string UiExtension::Version() const { return UI_EXTENSION_VERSION; }
|
|||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
|
#ifdef DUCKDB_CPP_EXTENSION_ENTRY
|
||||||
|
DUCKDB_CPP_EXTENSION_ENTRY(ui, loader) { duckdb::LoadInternal(loader); }
|
||||||
|
#else
|
||||||
DUCKDB_EXTENSION_API void ui_init(duckdb::DatabaseInstance &db) {
|
DUCKDB_EXTENSION_API void ui_init(duckdb::DatabaseInstance &db) {
|
||||||
duckdb::DuckDB db_wrapper(db);
|
duckdb::DuckDB db_wrapper(db);
|
||||||
db_wrapper.LoadExtension<duckdb::UiExtension>();
|
db_wrapper.LoadExtension<duckdb::UiExtension>();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
DUCKDB_EXTENSION_API const char *ui_version() {
|
DUCKDB_EXTENSION_API const char *ui_version() {
|
||||||
return duckdb::DuckDB::LibraryVersion();
|
return duckdb::DuckDB::LibraryVersion();
|
||||||
|
|||||||
Reference in New Issue
Block a user