First version
This commit is contained in:
60
src/utils/encoding.cpp
Normal file
60
src/utils/encoding.cpp
Normal file
@@ -0,0 +1,60 @@
|
||||
#include "utils/encoding.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace duckdb {
|
||||
|
||||
// Copied from https://www.mycplus.com/source-code/c-source-code/base64-encode-decode/
|
||||
constexpr char k_encoding_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+_";
|
||||
|
||||
std::vector<char> BuildDecodingTable() {
|
||||
std::vector<char> decoding_table;
|
||||
decoding_table.resize(256);
|
||||
for (int i = 0; i < 64; ++i) {
|
||||
decoding_table[static_cast<unsigned char>(k_encoding_table[i])] = i;
|
||||
}
|
||||
return decoding_table;
|
||||
}
|
||||
|
||||
const static std::vector<char> k_decoding_table = BuildDecodingTable();
|
||||
|
||||
std::string DecodeBase64(const std::string &data) {
|
||||
size_t input_length = data.size();
|
||||
if (input_length < 4 || input_length % 4 != 0) {
|
||||
// Handle this exception
|
||||
return "";
|
||||
}
|
||||
|
||||
size_t output_length = input_length / 4 * 3;
|
||||
if (data[input_length - 1] == '=') {
|
||||
output_length--;
|
||||
}
|
||||
if (data[input_length - 2] == '=') {
|
||||
output_length--;
|
||||
}
|
||||
|
||||
std::string decoded_data;
|
||||
decoded_data.resize(output_length);
|
||||
for (size_t i = 0, j = 0; i < input_length;) {
|
||||
uint32_t sextet_a = data[i] == '=' ? 0 & i++ : k_decoding_table[data[i++]];
|
||||
uint32_t sextet_b = data[i] == '=' ? 0 & i++ : k_decoding_table[data[i++]];
|
||||
uint32_t sextet_c = data[i] == '=' ? 0 & i++ : k_decoding_table[data[i++]];
|
||||
uint32_t sextet_d = data[i] == '=' ? 0 & i++ : k_decoding_table[data[i++]];
|
||||
|
||||
uint32_t triple = (sextet_a << 3 * 6) + (sextet_b << 2 * 6) + (sextet_c << 1 * 6) + (sextet_d << 0 * 6);
|
||||
|
||||
if (j < output_length) {
|
||||
decoded_data[j++] = (triple >> 2 * 8) & 0xFF;
|
||||
}
|
||||
if (j < output_length) {
|
||||
decoded_data[j++] = (triple >> 1 * 8) & 0xFF;
|
||||
}
|
||||
if (j < output_length) {
|
||||
decoded_data[j++] = (triple >> 0 * 8) & 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
return decoded_data;
|
||||
}
|
||||
|
||||
} // namespace duckdb
|
||||
34
src/utils/env.cpp
Normal file
34
src/utils/env.cpp
Normal file
@@ -0,0 +1,34 @@
|
||||
#include "utils/env.hpp"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <duckdb.hpp>
|
||||
|
||||
namespace duckdb {
|
||||
|
||||
const char *TryGetEnv(const char *name) {
|
||||
const char *res = std::getenv(name);
|
||||
if (res) {
|
||||
return res;
|
||||
}
|
||||
return std::getenv(StringUtil::Upper(name).c_str());
|
||||
}
|
||||
|
||||
std::string GetEnvOrDefault(const char *name, const char *default_value) {
|
||||
const char *res = TryGetEnv(name);
|
||||
if (res) {
|
||||
return res;
|
||||
}
|
||||
return default_value;
|
||||
}
|
||||
|
||||
bool IsEnvEnabled(const char *name) {
|
||||
const char *res = TryGetEnv(name);
|
||||
if (!res) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto lc_res = StringUtil::Lower(res);
|
||||
return lc_res == "1" || lc_res == "true";
|
||||
}
|
||||
|
||||
} // namespace duckdb
|
||||
30
src/utils/helpers.cpp
Normal file
30
src/utils/helpers.cpp
Normal file
@@ -0,0 +1,30 @@
|
||||
#include "utils/helpers.hpp"
|
||||
#include <duckdb/main/extension_util.hpp>
|
||||
|
||||
namespace duckdb {
|
||||
|
||||
bool ShouldRun(TableFunctionInput &input) {
|
||||
auto state = dynamic_cast<RunOnceTableFunctionState *>(input.global_state.get());
|
||||
D_ASSERT(state != nullptr);
|
||||
if (state->run) {
|
||||
return false;
|
||||
}
|
||||
|
||||
state->run = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
unique_ptr<FunctionData> ResultBind(ClientContext &, TableFunctionBindInput &,
|
||||
vector<LogicalType> &out_types,
|
||||
vector<std::string> &out_names) {
|
||||
out_names.emplace_back("result");
|
||||
out_types.emplace_back(LogicalType::VARCHAR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void RegisterTF(DatabaseInstance &instance, const char* name, table_function_t func) {
|
||||
TableFunction tf(name, {}, func, ResultBind, RunOnceTableFunctionState::Init);
|
||||
ExtensionUtil::RegisterFunction(instance, tf);
|
||||
}
|
||||
|
||||
} // namespace duckdb
|
||||
49
src/utils/serialization.cpp
Normal file
49
src/utils/serialization.cpp
Normal file
@@ -0,0 +1,49 @@
|
||||
#include "utils/serialization.hpp"
|
||||
|
||||
#include "duckdb/common/serializer/deserializer.hpp"
|
||||
#include "duckdb/common/serializer/serializer.hpp"
|
||||
|
||||
namespace duckdb {
|
||||
namespace ui {
|
||||
|
||||
void EmptyResult::Serialize(Serializer &) const {
|
||||
}
|
||||
|
||||
void TokenizeResult::Serialize(Serializer &serializer) const {
|
||||
serializer.WriteProperty(100, "offsets", offsets);
|
||||
serializer.WriteProperty(101, "types", types);
|
||||
}
|
||||
|
||||
// Adapted from parts of DataChunk::Serialize
|
||||
void ColumnNamesAndTypes::Serialize(Serializer &serializer) const {
|
||||
serializer.WriteProperty(100, "names", names);
|
||||
serializer.WriteProperty(101, "types", types);
|
||||
}
|
||||
|
||||
// Adapted from parts of DataChunk::Serialize
|
||||
void Chunk::Serialize(Serializer &serializer) const {
|
||||
serializer.WriteProperty(100, "row_count", row_count);
|
||||
serializer.WriteList(101, "vectors", vectors.size(), [&](Serializer::List &list, idx_t i) {
|
||||
list.WriteObject([&](Serializer &object) {
|
||||
// Reference the vector to avoid potentially mutating it during serialization
|
||||
Vector serialized_vector(vectors[i].GetType());
|
||||
serialized_vector.Reference(vectors[i]);
|
||||
serialized_vector.Serialize(object, row_count);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void SuccessResult::Serialize(Serializer &serializer) const {
|
||||
serializer.WriteProperty(100, "success", true);
|
||||
serializer.WriteProperty(101, "column_names_and_types", column_names_and_types);
|
||||
serializer.WriteList(102, "chunks", chunks.size(),
|
||||
[&](Serializer::List &list, idx_t i) { list.WriteElement(chunks[i]); });
|
||||
}
|
||||
|
||||
void ErrorResult::Serialize(Serializer &serializer) const {
|
||||
serializer.WriteProperty(100, "success", false);
|
||||
serializer.WriteProperty(101, "error", error);
|
||||
}
|
||||
|
||||
} // namespace ui
|
||||
} // namespace duckdb
|
||||
Reference in New Issue
Block a user