diff --git a/librocksdb-sys/api/c.cc b/librocksdb-sys/api/c.cc index 9ffe710..9cf0448 100644 --- a/librocksdb-sys/api/c.cc +++ b/librocksdb-sys/api/c.cc @@ -1,14 +1,31 @@ +#include "../rocksdb/db/c.cc" #include "../rocksdb/include/rocksdb/version.h" #include #include "c.h" -static char* CopyString(const std::string& str) { - char* result = reinterpret_cast(malloc(sizeof(char) * str.size()+1)); - memcpy(result, str.data(), sizeof(char) * str.size()); - result[sizeof(char) * str.size()] = 0; - return result; +// static char* CopyString(const std::string& str) { +// char* result = reinterpret_cast(malloc(sizeof(char) * str.size()+1)); +// memcpy(result, str.data(), sizeof(char) * str.size()); +// result[sizeof(char) * str.size()] = 0; +// return result; +// } + +static bool SaveStatus(rocksdb_status_t* target, const Status source) { + target->code = static_cast(source.code()); + target->subcode = static_cast(source.subcode()); + target->severity = static_cast(source.severity()); + if (source.ok()) { + target->string = nullptr; + } else { + std::string msg = source.ToString(); + char* string = new char[msg.size() + 1]; // we need extra char for NUL + memcpy(string, msg.c_str(), msg.size() + 1); + target->string = string; + } + return !source.ok(); } + extern "C" { char* rocksdb_version() { @@ -16,4 +33,305 @@ char* rocksdb_version() { return CopyString(name); } +rocksdb_pinnableslice_t* rocksdb_get_pinned_cf_with_status( + rocksdb_t* db, const rocksdb_readoptions_t* options, + rocksdb_column_family_handle_t* column_family, const char* key, + size_t keylen, rocksdb_status_t* statusptr) { + rocksdb_pinnableslice_t* v = new (rocksdb_pinnableslice_t); + Status s = db->rep->Get(options->rep, column_family->rep, Slice(key, keylen), + &v->rep); + if (!s.ok()) { + delete v; + if (!s.IsNotFound()) { + SaveStatus(statusptr, s); + } + return nullptr; + } + return v; +} + +rocksdb_t* rocksdb_open_for_read_only_column_families_with_status( + const rocksdb_options_t* db_options, const char* name, + int num_column_families, const char* const* column_family_names, + const rocksdb_options_t* const* column_family_options, + rocksdb_column_family_handle_t** column_family_handles, + unsigned char error_if_wal_file_exists, rocksdb_status_t* statusptr) { + std::vector column_families; + for (int i = 0; i < num_column_families; i++) { + column_families.emplace_back(ColumnFamilyDescriptor( + std::string(column_family_names[i]), + ColumnFamilyOptions(column_family_options[i]->rep))); + } + + DB* db; + std::vector handles; + if (SaveStatus(statusptr, DB::OpenForReadOnly(DBOptions(db_options->rep), + std::string(name), + column_families, &handles, &db, + error_if_wal_file_exists))) { + return nullptr; + } + + for (size_t i = 0; i < handles.size(); i++) { + rocksdb_column_family_handle_t* c_handle = + new rocksdb_column_family_handle_t; + c_handle->rep = handles[i]; + column_family_handles[i] = c_handle; + } + rocksdb_t* result = new rocksdb_t; + result->rep = db; + return result; +} + +void rocksdb_try_catch_up_with_primary_with_status( + rocksdb_t* db, rocksdb_status_t* statusptr) { + SaveStatus(statusptr, db->rep->TryCatchUpWithPrimary()); +} + +rocksdb_t* rocksdb_open_as_secondary_column_families_with_status( + const rocksdb_options_t* db_options, const char* name, + const char* secondary_path, int num_column_families, + const char* const* column_family_names, + const rocksdb_options_t* const* column_family_options, + rocksdb_column_family_handle_t** column_family_handles, + rocksdb_status_t* statusptr) { + std::vector column_families; + for (int i = 0; i != num_column_families; ++i) { + column_families.emplace_back( + std::string(column_family_names[i]), + ColumnFamilyOptions(column_family_options[i]->rep)); + } + DB* db; + std::vector handles; + if (SaveStatus(statusptr, DB::OpenAsSecondary( + DBOptions(db_options->rep), std::string(name), + std::string(secondary_path), column_families, + &handles, &db))) { + return nullptr; + } + for (size_t i = 0; i != handles.size(); ++i) { + rocksdb_column_family_handle_t* c_handle = + new rocksdb_column_family_handle_t; + c_handle->rep = handles[i]; + column_family_handles[i] = c_handle; + } + rocksdb_t* result = new rocksdb_t; + result->rep = db; + return result; +} + +void rocksdb_create_checkpoint_with_status(rocksdb_t* db, + const char* checkpoint_dir, + rocksdb_status_t* statusptr) { + Checkpoint* checkpoint; + Status s = Checkpoint::Create(db->rep, &checkpoint); + if (!s.ok()) { + SaveStatus(statusptr, s); + return; + } + SaveStatus(statusptr, + checkpoint->CreateCheckpoint(std::string(checkpoint_dir))); + delete checkpoint; +} + +rocksdb_transactiondb_t* rocksdb_transactiondb_open_column_families_with_status( + const rocksdb_options_t* options, + const rocksdb_transactiondb_options_t* txn_db_options, const char* name, + int num_column_families, const char* const* column_family_names, + const rocksdb_options_t* const* column_family_options, + rocksdb_column_family_handle_t** column_family_handles, + rocksdb_status_t* statusptr) { + std::vector column_families; + for (int i = 0; i < num_column_families; i++) { + column_families.emplace_back(ColumnFamilyDescriptor( + std::string(column_family_names[i]), + ColumnFamilyOptions(column_family_options[i]->rep))); + } + + TransactionDB* txn_db; + std::vector handles; + if (SaveStatus(statusptr, + TransactionDB::Open(options->rep, txn_db_options->rep, + std::string(name), column_families, + &handles, &txn_db))) { + return nullptr; + } + + for (size_t i = 0; i < handles.size(); i++) { + rocksdb_column_family_handle_t* c_handle = + new rocksdb_column_family_handle_t; + c_handle->rep = handles[i]; + column_family_handles[i] = c_handle; + } + rocksdb_transactiondb_t* result = new rocksdb_transactiondb_t; + result->rep = txn_db; + return result; +} + +rocksdb_pinnableslice_t* rocksdb_transactiondb_get_pinned_cf_with_status( + rocksdb_transactiondb_t* db, const rocksdb_readoptions_t* options, + rocksdb_column_family_handle_t* column_family, const char* key, + size_t keylen, rocksdb_status_t* statusptr) { + rocksdb_pinnableslice_t* v = new rocksdb_pinnableslice_t; + Status s = db->rep->Get(options->rep, column_family->rep, Slice(key, keylen), + &v->rep); + if (!s.ok()) { + delete v; + if (!s.IsNotFound()) { + SaveStatus(statusptr, s); + } + return nullptr; + } + return v; +} + +void rocksdb_transactiondb_put_cf_with_status( + rocksdb_transactiondb_t* txn_db, const rocksdb_writeoptions_t* options, + rocksdb_column_family_handle_t* column_family, const char* key, + size_t keylen, const char* val, size_t vallen, + rocksdb_status_t* statusptr) { + SaveStatus(statusptr, + txn_db->rep->Put(options->rep, column_family->rep, + Slice(key, keylen), Slice(val, vallen))); +} + +void rocksdb_transactiondb_flush_cf_with_status( + rocksdb_transactiondb_t* db, const rocksdb_flushoptions_t* options, + rocksdb_column_family_handle_t* column_family, + rocksdb_status_t* statusptr) { + SaveStatus(statusptr, db->rep->Flush(options->rep, column_family->rep)); +} + +void rocksdb_transactiondb_compact_range_cf_opt_with_status( + rocksdb_transactiondb_t* db, rocksdb_column_family_handle_t* column_family, + rocksdb_compactoptions_t* opt, const char* start_key, size_t start_key_len, + const char* limit_key, size_t limit_key_len, rocksdb_status_t* statusptr) { + Slice a, b; + SaveStatus( + statusptr, + db->rep->CompactRange( + opt->rep, column_family->rep, + // Pass nullptr Slice if corresponding "const char*" is nullptr + (start_key ? (a = Slice(start_key, start_key_len), &a) : nullptr), + (limit_key ? (b = Slice(limit_key, limit_key_len), &b) : nullptr))); +} + +void rocksdb_transactiondb_ingest_external_files_with_status( + rocksdb_transactiondb_t* db, const rocksdb_ingestexternalfilearg_t* list, + const size_t list_len, rocksdb_status_t* statusptr) { + std::vector args(list_len); + for (size_t i = 0; i < list_len; ++i) { + args[i].column_family = list[i].column_family->rep; + std::vector files(list[i].external_files_len); + for (size_t j = 0; j < list[i].external_files_len; ++j) { + files[j] = std::string(list[i].external_files[j]); + } + args[i].external_files = files; + args[i].options = list[i].options->rep; + } + SaveStatus(statusptr, db->rep->IngestExternalFiles(args)); +} + +void rocksdb_transactiondb_create_checkpoint_with_status( + rocksdb_transactiondb_t* db, const char* checkpoint_dir, + rocksdb_status_t* statusptr) { + Checkpoint* checkpoint; + Status s = Checkpoint::Create(db->rep, &checkpoint); + if (!s.ok()) { + SaveStatus(statusptr, s); + return; + } + SaveStatus(statusptr, + checkpoint->CreateCheckpoint(std::string(checkpoint_dir))); + delete checkpoint; +} + +void rocksdb_transaction_commit_with_status(rocksdb_transaction_t* txn, + rocksdb_status_t* statusptr) { + SaveStatus(statusptr, txn->rep->Commit()); +} + +void rocksdb_transaction_rollback_with_status(rocksdb_transaction_t* txn, + rocksdb_status_t* statusptr) { + SaveStatus(statusptr, txn->rep->Rollback()); +} + +rocksdb_pinnableslice_t* rocksdb_transaction_get_pinned_cf_with_status( + rocksdb_transaction_t* txn, const rocksdb_readoptions_t* options, + rocksdb_column_family_handle_t* column_family, const char* key, + size_t keylen, rocksdb_status_t* statusptr) { + rocksdb_pinnableslice_t* v = new rocksdb_pinnableslice_t; + Status s = txn->rep->Get(options->rep, column_family->rep, Slice(key, keylen), + &v->rep); + if (!s.ok()) { + delete v; + if (!s.IsNotFound()) { + SaveStatus(statusptr, s); + } + return nullptr; + } + return v; +} + +rocksdb_pinnableslice_t* +rocksdb_transaction_get_for_update_pinned_cf_with_status( + rocksdb_transaction_t* txn, const rocksdb_readoptions_t* options, + rocksdb_column_family_handle_t* column_family, const char* key, + size_t keylen, rocksdb_status_t* statusptr) { + rocksdb_pinnableslice_t* v = new rocksdb_pinnableslice_t; + Status s = txn->rep->GetForUpdate(options->rep, column_family->rep, + Slice(key, keylen), &v->rep); + if (!s.ok()) { + delete v; + if (!s.IsNotFound()) { + SaveStatus(statusptr, s); + } + return nullptr; + } + return v; +} + +void rocksdb_transaction_put_cf_with_status( + rocksdb_transaction_t* txn, rocksdb_column_family_handle_t* column_family, + const char* key, size_t klen, const char* val, size_t vlen, + rocksdb_status_t* statusptr) { + SaveStatus(statusptr, txn->rep->Put(column_family->rep, Slice(key, klen), + Slice(val, vlen))); +} + +void rocksdb_transaction_delete_cf_with_status( + rocksdb_transaction_t* txn, rocksdb_column_family_handle_t* column_family, + const char* key, size_t klen, rocksdb_status_t* statusptr) { + SaveStatus(statusptr, txn->rep->Delete(column_family->rep, Slice(key, klen))); +} + +void rocksdb_sstfilewriter_open_with_status(rocksdb_sstfilewriter_t* writer, + const char* name, + rocksdb_status_t* statusptr) { + SaveStatus(statusptr, writer->rep->Open(std::string(name))); +} + +void rocksdb_sstfilewriter_put_with_status(rocksdb_sstfilewriter_t* writer, + const char* key, size_t keylen, + const char* val, size_t vallen, + rocksdb_status_t* statusptr) { + SaveStatus(statusptr, + writer->rep->Put(Slice(key, keylen), Slice(val, vallen))); +} + +void rocksdb_sstfilewriter_finish_with_status(rocksdb_sstfilewriter_t* writer, + rocksdb_status_t* statusptr) { + SaveStatus(statusptr, writer->rep->Finish(nullptr)); +} + +void rocksdb_iter_get_status(const rocksdb_iterator_t* iter, + rocksdb_status_t* statusptr) { + SaveStatus(statusptr, iter->rep->status()); +} + +rocksdb_readoptions_t* rocksdb_readoptions_create_copy( + rocksdb_readoptions_t* options) { + return new rocksdb_readoptions_t(*options); +} + } diff --git a/librocksdb-sys/api/c.h b/librocksdb-sys/api/c.h index a40e1fc..369a0d8 100644 --- a/librocksdb-sys/api/c.h +++ b/librocksdb-sys/api/c.h @@ -1,11 +1,185 @@ #pragma once +#include "../rocksdb/include/rocksdb/c.h" + #ifdef __cplusplus extern "C" { #endif char* rocksdb_version(); +typedef enum rocksdb_status_code_t { + rocksdb_status_code_ok = 0, + rocksdb_status_code_not_found = 1, + rocksdb_status_code_corruption = 2, + rocksdb_status_code_not_supported = 3, + rocksdb_status_code_invalid_argument = 4, + rocksdb_status_code_io_error = 5, + rocksdb_status_code_merge_in_progress = 6, + rocksdb_status_code_incomplete = 7, + rocksdb_status_code_shutdown_in_progress = 8, + rocksdb_status_code_timed_out = 9, + rocksdb_status_code_aborted = 10, + rocksdb_status_code_busy = 11, + rocksdb_status_code_expired = 12, + rocksdb_status_code_try_again = 13, + rocksdb_status_code_compaction_too_large = 14, + rocksdb_status_code_column_family_dropped = 15, +} rocksdb_status_code_t; + +typedef enum rocksdb_status_subcode_t { + rocksdb_status_subcode_none = 0, + rocksdb_status_subcode_mutex_timeout = 1, + rocksdb_status_subcode_lock_timeout = 2, + rocksdb_status_subcode_lock_limit = 3, + rocksdb_status_subcode_no_space = 4, + rocksdb_status_subcode_deadlock = 5, + rocksdb_status_subcode_stale_file = 6, + rocksdb_status_subcode_memory_limit = 7, + rocksdb_status_subcode_space_limit = 8, + rocksdb_status_subcode_path_not_found = 9, + rocksdb_status_subcode_merge_operands_insufficient_capacity = 10, + rocksdb_status_subcode_manual_compaction_paused = 11, + rocksdb_status_subcode_overwritten = 12, + rocksdb_status_subcode_txn_not_prepared = 13, + rocksdb_status_subcode_io_fenced = 14, + rocksdb_status_subcode_merge_operator_failed = 15, +} rocksdb_status_subcode_t; + +typedef enum rocksdb_status_severity_t { + rocksdb_status_severity_none = 0, + rocksdb_status_severity_soft_error = 1, + rocksdb_status_severity_hard_error = 2, + rocksdb_status_severity_fatal_error = 3, + rocksdb_status_severity_unrecoverable_error = 4, +} rocksdb_status_severity_t; + +typedef struct rocksdb_status_t { + rocksdb_status_code_t code; + rocksdb_status_subcode_t subcode; + rocksdb_status_severity_t severity; + const char* string; +} rocksdb_status_t; + +typedef struct rocksdb_ingestexternalfilearg_t { + rocksdb_column_family_handle_t* column_family; + char const* const* external_files; + size_t external_files_len; + rocksdb_ingestexternalfileoptions_t* options; +} rocksdb_ingestexternalfilearg_t; + +rocksdb_pinnableslice_t* rocksdb_get_pinned_cf_with_status( + rocksdb_t* db, const rocksdb_readoptions_t* options, + rocksdb_column_family_handle_t* column_family, const char* key, + size_t keylen, rocksdb_status_t* statusptr); + +extern ROCKSDB_LIBRARY_API rocksdb_t* +rocksdb_open_for_read_only_column_families_with_status( + const rocksdb_options_t* db_options, const char* name, + int num_column_families, const char* const* column_family_names, + const rocksdb_options_t* const* column_family_options, + rocksdb_column_family_handle_t** column_family_handles, + unsigned char error_if_wal_file_exists, rocksdb_status_t* statusptr); + +extern ROCKSDB_LIBRARY_API void rocksdb_try_catch_up_with_primary_with_status( + rocksdb_t* db, rocksdb_status_t* statusptr); + +extern ROCKSDB_LIBRARY_API rocksdb_t* +rocksdb_open_as_secondary_column_families_with_status( + const rocksdb_options_t* options, const char* name, + const char* secondary_path, int num_column_families, + const char* const* column_family_names, + const rocksdb_options_t* const* column_family_options, + rocksdb_column_family_handle_t** column_family_handles, + rocksdb_status_t* statusptr); + +extern ROCKSDB_LIBRARY_API void rocksdb_create_checkpoint_with_status( + rocksdb_t* db, const char* checkpoint_dir, rocksdb_status_t* statusptr); + +extern ROCKSDB_LIBRARY_API rocksdb_transactiondb_t* +rocksdb_transactiondb_open_column_families_with_status( + const rocksdb_options_t* options, + const rocksdb_transactiondb_options_t* txn_db_options, const char* name, + int num_column_families, const char* const* column_family_names, + const rocksdb_options_t* const* column_family_options, + rocksdb_column_family_handle_t** column_family_handles, + rocksdb_status_t* statusptr); + +extern ROCKSDB_LIBRARY_API rocksdb_pinnableslice_t* +rocksdb_transactiondb_get_pinned_cf_with_status( + rocksdb_transactiondb_t* db, const rocksdb_readoptions_t* options, + rocksdb_column_family_handle_t* column_family, const char* key, + size_t keylen, rocksdb_status_t* statusptr); + +extern ROCKSDB_LIBRARY_API void rocksdb_transactiondb_put_cf_with_status( + rocksdb_transactiondb_t* txn_db, const rocksdb_writeoptions_t* options, + rocksdb_column_family_handle_t* column_family, const char* key, + size_t keylen, const char* val, size_t vallen, rocksdb_status_t* statusptr); + +extern ROCKSDB_LIBRARY_API void rocksdb_transactiondb_flush_cf_with_status( + rocksdb_transactiondb_t* db, const rocksdb_flushoptions_t* options, + rocksdb_column_family_handle_t* column_family, rocksdb_status_t* statusptr); + +extern ROCKSDB_LIBRARY_API void +rocksdb_transactiondb_compact_range_cf_opt_with_status( + rocksdb_transactiondb_t* db, rocksdb_column_family_handle_t* column_family, + rocksdb_compactoptions_t* opt, const char* start_key, size_t start_key_len, + const char* limit_key, size_t limit_key_len, rocksdb_status_t* statusptr); + +extern ROCKSDB_LIBRARY_API void +rocksdb_transactiondb_ingest_external_files_with_status( + rocksdb_transactiondb_t* db, const rocksdb_ingestexternalfilearg_t* list, + const size_t list_len, rocksdb_status_t* statusptr); + +extern ROCKSDB_LIBRARY_API void +rocksdb_transactiondb_create_checkpoint_with_status( + rocksdb_transactiondb_t* db, const char* checkpoint_dir, + rocksdb_status_t* statusptr); + +extern ROCKSDB_LIBRARY_API void rocksdb_transaction_commit_with_status( + rocksdb_transaction_t* txn, rocksdb_status_t* statusptr); + +extern ROCKSDB_LIBRARY_API void rocksdb_transaction_rollback_with_status( + rocksdb_transaction_t* txn, rocksdb_status_t* statusptr); + +extern ROCKSDB_LIBRARY_API rocksdb_pinnableslice_t* +rocksdb_transaction_get_pinned_cf_with_status( + rocksdb_transaction_t* txn, const rocksdb_readoptions_t* options, + rocksdb_column_family_handle_t* column_family, const char* key, + size_t keylen, rocksdb_status_t* statusptr); + +extern ROCKSDB_LIBRARY_API rocksdb_pinnableslice_t* +rocksdb_transaction_get_for_update_pinned_cf_with_status( + rocksdb_transaction_t* txn, const rocksdb_readoptions_t* options, + rocksdb_column_family_handle_t* column_family, const char* key, + size_t keylen, rocksdb_status_t* statusptr); + +extern ROCKSDB_LIBRARY_API void rocksdb_transaction_put_cf_with_status( + rocksdb_transaction_t* txn, rocksdb_column_family_handle_t* column_family, + const char* key, size_t klen, const char* val, size_t vlen, + rocksdb_status_t* statusptr); + +extern ROCKSDB_LIBRARY_API void rocksdb_transaction_delete_cf_with_status( + rocksdb_transaction_t* txn, rocksdb_column_family_handle_t* column_family, + const char* key, size_t klen, rocksdb_status_t* statusptr); + +extern ROCKSDB_LIBRARY_API void rocksdb_sstfilewriter_open_with_status( + rocksdb_sstfilewriter_t* writer, const char* name, + rocksdb_status_t* statusptr); + +extern ROCKSDB_LIBRARY_API void rocksdb_sstfilewriter_put_with_status( + rocksdb_sstfilewriter_t* writer, const char* key, size_t keylen, + const char* val, size_t vallen, rocksdb_status_t* statusptr); + +extern ROCKSDB_LIBRARY_API void rocksdb_sstfilewriter_finish_with_status( + rocksdb_sstfilewriter_t* writer, rocksdb_status_t* statusptr); + +extern ROCKSDB_LIBRARY_API void rocksdb_iter_get_status( + const rocksdb_iterator_t*, rocksdb_status_t* statusptr); + +extern ROCKSDB_LIBRARY_API rocksdb_readoptions_t* +rocksdb_readoptions_create_copy(rocksdb_readoptions_t*); + #ifdef __cplusplus } #endif