#pragma once
#include <array>
#include <cstdint>
#include <memory>
#include <string>
#include <string_view>
#include <unordered_map>
#include <vector>
#include "rust/cxx.h"
#ifdef LBUG_BUNDLED
#include "c_api/lbug.h"
#include "main/lbug.h"
#else
#include <lbug.h>
#include <lbug.hpp>
#endif
namespace lbug_rs {
using ArrowArray = ::ArrowArray;
using ArrowSchema = ::ArrowSchema;
struct ArrowArrayList {
std::vector<ArrowArray> arrays;
};
std::unique_ptr<ArrowArrayList> new_arrow_array_list();
inline void arrow_array_list_push(ArrowArrayList& list, ArrowArray array) {
list.arrays.push_back(array);
}
struct TypeListBuilder {
std::vector<lbug::common::LogicalType> types;
void insert(std::unique_ptr<lbug::common::LogicalType> type) {
types.push_back(std::move(*type));
}
};
std::unique_ptr<TypeListBuilder> create_type_list();
inline void type_list_insert(TypeListBuilder& list,
std::unique_ptr<lbug::common::LogicalType> type) {
list.insert(std::move(type));
}
struct QueryParams {
std::unordered_map<std::string, std::unique_ptr<lbug::common::Value>> inputParams;
void insert(const rust::Str key, std::unique_ptr<lbug::common::Value> value) {
inputParams.insert(std::make_pair(key, std::move(value)));
}
};
std::unique_ptr<QueryParams> new_params();
inline void query_params_insert(QueryParams& params, const rust::Str key,
std::unique_ptr<lbug::common::Value> value) {
params.insert(key, std::move(value));
}
std::unique_ptr<lbug::common::LogicalType> create_logical_type(lbug::common::LogicalTypeID id);
std::unique_ptr<lbug::common::LogicalType> create_logical_type_list(
std::unique_ptr<lbug::common::LogicalType> childType);
std::unique_ptr<lbug::common::LogicalType> create_logical_type_array(
std::unique_ptr<lbug::common::LogicalType> childType, uint64_t numElements);
inline std::unique_ptr<lbug::common::LogicalType> create_logical_type_struct(
const rust::Vec<rust::String>& fieldNames, std::unique_ptr<TypeListBuilder> fieldTypes) {
std::vector<lbug::common::StructField> fields;
for (auto i = 0u; i < fieldNames.size(); i++) {
fields.emplace_back(std::string(fieldNames[i]), std::move(fieldTypes->types[i]));
}
return std::make_unique<lbug::common::LogicalType>(
lbug::common::LogicalType::STRUCT(std::move(fields)));
}
inline std::unique_ptr<lbug::common::LogicalType> create_logical_type_union(
const rust::Vec<rust::String>& fieldNames, std::unique_ptr<TypeListBuilder> fieldTypes) {
std::vector<lbug::common::StructField> fields;
for (auto i = 0u; i < fieldNames.size(); i++) {
fields.emplace_back(std::string(fieldNames[i]), std::move(fieldTypes->types[i]));
}
return std::make_unique<lbug::common::LogicalType>(
lbug::common::LogicalType::UNION(std::move(fields)));
}
std::unique_ptr<lbug::common::LogicalType> create_logical_type_map(
std::unique_ptr<lbug::common::LogicalType> keyType,
std::unique_ptr<lbug::common::LogicalType> valueType);
inline std::unique_ptr<lbug::common::LogicalType> create_logical_type_decimal(uint32_t precision,
uint32_t scale) {
return std::make_unique<lbug::common::LogicalType>(
lbug::common::LogicalType::DECIMAL(precision, scale));
}
std::unique_ptr<lbug::common::LogicalType> logical_type_get_list_child_type(
const lbug::common::LogicalType& logicalType);
std::unique_ptr<lbug::common::LogicalType> logical_type_get_array_child_type(
const lbug::common::LogicalType& logicalType);
uint64_t logical_type_get_array_num_elements(const lbug::common::LogicalType& logicalType);
rust::Vec<rust::String> logical_type_get_struct_field_names(const lbug::common::LogicalType& value);
std::unique_ptr<std::vector<lbug::common::LogicalType>> logical_type_get_struct_field_types(
const lbug::common::LogicalType& value);
inline uint32_t logical_type_get_decimal_precision(const lbug::common::LogicalType& logicalType) {
return lbug::common::DecimalType::getPrecision(logicalType);
}
inline uint32_t logical_type_get_decimal_scale(const lbug::common::LogicalType& logicalType) {
return lbug::common::DecimalType::getScale(logicalType);
}
inline lbug::common::LogicalTypeID logical_type_get_logical_type_id(
const lbug::common::LogicalType& logicalType) {
return logicalType.getLogicalTypeID();
}
std::unique_ptr<lbug::main::Database> new_database(std::string_view databasePath,
uint64_t bufferPoolSize, uint64_t maxNumThreads, bool enableCompression, bool readOnly,
uint64_t maxDBSize, bool autoCheckpoint, int64_t checkpointThreshold,
bool throwOnWalReplayFailure, bool enableChecksums, bool enableMultiWrites);
void database_set_logging_level(lbug::main::Database& database, const std::string& level);
std::unique_ptr<lbug::main::Connection> database_connect(lbug::main::Database& database);
std::unique_ptr<lbug::main::QueryResult> connection_execute(lbug::main::Connection& connection,
lbug::main::PreparedStatement& query, std::unique_ptr<QueryParams> params);
inline std::unique_ptr<lbug::main::QueryResult> connection_query(lbug::main::Connection& connection,
std::string_view query) {
return connection.query(query);
}
inline std::unique_ptr<lbug::main::QueryResult> connection_query_as_arrow(
lbug::main::Connection& connection, std::string_view query, int64_t chunkSize) {
return connection.queryAsArrow(query, chunkSize);
}
std::unique_ptr<lbug::main::QueryResult> connection_create_arrow_table(
lbug::main::Connection& connection, std::string_view tableName, ArrowSchema schema,
std::unique_ptr<ArrowArrayList> arrays);
std::unique_ptr<lbug::main::QueryResult> connection_create_arrow_rel_table(
lbug::main::Connection& connection, std::string_view tableName, std::string_view srcTableName,
std::string_view dstTableName, ArrowSchema schema, std::unique_ptr<ArrowArrayList> arrays);
std::unique_ptr<lbug::main::QueryResult> connection_create_arrow_rel_table_csr(
lbug::main::Connection& connection, std::string_view tableName, std::string_view srcTableName,
std::string_view dstTableName, ArrowSchema indicesSchema,
std::unique_ptr<ArrowArrayList> indicesArrays, ArrowSchema indptrSchema,
std::unique_ptr<ArrowArrayList> indptrArrays, std::string_view dstColName = "to");
std::unique_ptr<lbug::main::QueryResult> connection_drop_arrow_table(
lbug::main::Connection& connection, std::string_view tableName);
inline std::unique_ptr<lbug::main::PreparedStatement> connection_prepare(
lbug::main::Connection& connection, std::string_view query) {
return connection.prepare(query);
}
inline uint64_t connection_get_max_num_thread_for_exec(lbug::main::Connection& connection) {
return connection.getMaxNumThreadForExec();
}
inline void connection_set_max_num_thread_for_exec(lbug::main::Connection& connection,
uint64_t numThreads) {
connection.setMaxNumThreadForExec(numThreads);
}
inline void connection_interrupt(lbug::main::Connection& connection) {
connection.interrupt();
}
inline void connection_set_query_timeout(lbug::main::Connection& connection, uint64_t timeoutMs) {
connection.setQueryTimeOut(timeoutMs);
}
rust::String prepared_statement_error_message(const lbug::main::PreparedStatement& statement);
inline bool prepared_statement_is_read_only(const lbug::main::PreparedStatement& statement) {
return statement.isReadOnly();
}
inline bool prepared_statement_is_success(const lbug::main::PreparedStatement& statement) {
return statement.isSuccess();
}
rust::String query_result_to_string(const lbug::main::QueryResult& result);
rust::String query_result_get_error_message(const lbug::main::QueryResult& result);
inline bool query_result_is_success(const lbug::main::QueryResult& result) {
return result.isSuccess();
}
inline bool query_result_has_next(const lbug::main::QueryResult& result) {
return result.hasNext();
}
inline std::shared_ptr<lbug::processor::FlatTuple> query_result_get_next(
lbug::main::QueryResult& result) {
return result.getNext();
}
double query_result_get_compiling_time(const lbug::main::QueryResult& result);
double query_result_get_execution_time(const lbug::main::QueryResult& result);
inline size_t query_result_get_num_columns(const lbug::main::QueryResult& result) {
return result.getNumColumns();
}
inline uint64_t query_result_get_num_tuples(const lbug::main::QueryResult& result) {
return result.getNumTuples();
}
std::unique_ptr<std::vector<lbug::common::LogicalType>> query_result_column_data_types(
const lbug::main::QueryResult& query_result);
rust::Vec<rust::String> query_result_column_names(const lbug::main::QueryResult& query_result);
rust::String node_value_get_label_name(const lbug::common::Value& val);
rust::String rel_value_get_label_name(const lbug::common::Value& val);
size_t node_value_get_num_properties(const lbug::common::Value& value);
size_t rel_value_get_num_properties(const lbug::common::Value& value);
rust::String node_value_get_property_name(const lbug::common::Value& value, size_t index);
rust::String rel_value_get_property_name(const lbug::common::Value& value, size_t index);
const lbug::common::Value& node_value_get_property_value(const lbug::common::Value& value,
size_t index);
const lbug::common::Value& rel_value_get_property_value(const lbug::common::Value& value,
size_t index);
const lbug::common::Value& node_value_get_node_id(const lbug::common::Value& val);
const lbug::common::Value& rel_value_get_src_id(const lbug::common::Value& val);
std::array<uint64_t, 2> rel_value_get_dst_id(const lbug::common::Value& val);
const lbug::common::Value& recursive_rel_get_nodes(const lbug::common::Value& val);
const lbug::common::Value& recursive_rel_get_rels(const lbug::common::Value& val);
uint32_t flat_tuple_len(const lbug::processor::FlatTuple& flatTuple);
const lbug::common::Value& flat_tuple_get_value(const lbug::processor::FlatTuple& flatTuple,
uint32_t index);
const std::string& value_get_string(const lbug::common::Value& value);
template<typename T>
std::unique_ptr<T> value_get_unique(const lbug::common::Value& value) {
return std::make_unique<T>(value.getValue<T>());
}
int64_t value_get_interval_secs(const lbug::common::Value& value);
int32_t value_get_interval_micros(const lbug::common::Value& value);
int32_t value_get_date_days(const lbug::common::Value& value);
int64_t value_get_timestamp_ns(const lbug::common::Value& value);
int64_t value_get_timestamp_ms(const lbug::common::Value& value);
int64_t value_get_timestamp_sec(const lbug::common::Value& value);
int64_t value_get_timestamp_micros(const lbug::common::Value& value);
int64_t value_get_timestamp_tz(const lbug::common::Value& value);
std::array<uint64_t, 2> value_get_int128_t(const lbug::common::Value& value);
std::array<uint64_t, 2> value_get_internal_id(const lbug::common::Value& value);
uint32_t value_get_children_size(const lbug::common::Value& value);
const lbug::common::Value& value_get_child(const lbug::common::Value& value, uint32_t index);
lbug::common::LogicalTypeID value_get_data_type_id(const lbug::common::Value& value);
const lbug::common::LogicalType& value_get_data_type(const lbug::common::Value& value);
inline lbug::common::PhysicalTypeID value_get_physical_type(const lbug::common::Value& value) {
return value.getDataType().getPhysicalType();
}
rust::String value_to_string(const lbug::common::Value& val);
inline bool value_get_bool(const lbug::common::Value& value) {
return value.getValue<bool>();
}
inline int8_t value_get_i8(const lbug::common::Value& value) {
return value.getValue<int8_t>();
}
inline int16_t value_get_i16(const lbug::common::Value& value) {
return value.getValue<int16_t>();
}
inline int32_t value_get_i32(const lbug::common::Value& value) {
return value.getValue<int32_t>();
}
inline int64_t value_get_i64(const lbug::common::Value& value) {
return value.getValue<int64_t>();
}
inline uint8_t value_get_u8(const lbug::common::Value& value) {
return value.getValue<uint8_t>();
}
inline uint16_t value_get_u16(const lbug::common::Value& value) {
return value.getValue<uint16_t>();
}
inline uint32_t value_get_u32(const lbug::common::Value& value) {
return value.getValue<uint32_t>();
}
inline uint64_t value_get_u64(const lbug::common::Value& value) {
return value.getValue<uint64_t>();
}
inline float value_get_float(const lbug::common::Value& value) {
return value.getValue<float>();
}
inline double value_get_double(const lbug::common::Value& value) {
return value.getValue<double>();
}
inline bool value_is_null(const lbug::common::Value& value) {
return value.isNull();
}
std::unique_ptr<lbug::common::Value> create_value_string(lbug::common::LogicalTypeID typ,
const rust::Slice<const unsigned char> value);
std::unique_ptr<lbug::common::Value> create_value_timestamp(const int64_t timestamp);
std::unique_ptr<lbug::common::Value> create_value_timestamp_tz(const int64_t timestamp);
std::unique_ptr<lbug::common::Value> create_value_timestamp_ns(const int64_t timestamp);
std::unique_ptr<lbug::common::Value> create_value_timestamp_ms(const int64_t timestamp);
std::unique_ptr<lbug::common::Value> create_value_timestamp_sec(const int64_t timestamp);
inline std::unique_ptr<lbug::common::Value> create_value_date(const int32_t date) {
return std::make_unique<lbug::common::Value>(lbug::common::date_t(date));
}
std::unique_ptr<lbug::common::Value> create_value_interval(const int32_t months, const int32_t days,
const int64_t micros);
std::unique_ptr<lbug::common::Value> create_value_null(
std::unique_ptr<lbug::common::LogicalType> typ);
std::unique_ptr<lbug::common::Value> create_value_int128_t(int64_t high, uint64_t low);
std::unique_ptr<lbug::common::Value> create_value_internal_id(uint64_t offset, uint64_t table);
inline std::unique_ptr<lbug::common::Value> create_value_uuid_t(int64_t high, uint64_t low) {
return std::make_unique<lbug::common::Value>(
lbug::common::uuid{lbug::common::int128_t(low, high)});
}
template<typename T>
std::unique_ptr<lbug::common::Value> create_value(const T value) {
return std::make_unique<lbug::common::Value>(value);
}
inline std::unique_ptr<lbug::common::Value> create_value_decimal(int64_t high, uint64_t low,
uint32_t scale, uint32_t precision) {
auto value =
std::make_unique<lbug::common::Value>(lbug::common::LogicalType::DECIMAL(precision, scale),
std::vector<std::unique_ptr<lbug::common::Value>>{});
auto i128 = lbug::common::int128_t(low, high);
lbug::common::TypeUtils::visit(
value->getDataType().getPhysicalType(),
[&](lbug::common::int128_t) { value->val.int128Val = i128; },
[&](int64_t) { value->val.int64Val = static_cast<int64_t>(i128); },
[&](int32_t) { value->val.int32Val = static_cast<int32_t>(i128); },
[&](int16_t) { value->val.int16Val = static_cast<int16_t>(i128); },
[](auto) { UNREACHABLE_CODE; });
return value;
}
struct ValueListBuilder {
std::vector<std::unique_ptr<lbug::common::Value>> values;
void insert(std::unique_ptr<lbug::common::Value> value) { values.push_back(std::move(value)); }
};
std::unique_ptr<lbug::common::Value> get_list_value(std::unique_ptr<lbug::common::LogicalType> typ,
std::unique_ptr<ValueListBuilder> value);
std::unique_ptr<ValueListBuilder> create_list();
inline void value_list_insert(ValueListBuilder& list, std::unique_ptr<lbug::common::Value> value) {
list.insert(std::move(value));
}
inline std::string_view string_view_from_str(rust::Str s) {
return {s.data(), s.size()};
}
inline lbug::storage::storage_version_t get_storage_version() {
return lbug::storage::StorageVersionInfo::getStorageVersion();
}
}