2026-02-15 13:56:08 -05:00
|
|
|
#include "rocksdb_shim.h"
|
|
|
|
|
#include <rocksdb/db.h>
|
|
|
|
|
#include <rocksdb/options.h>
|
|
|
|
|
#include <rocksdb/slice.h>
|
|
|
|
|
#include <cstring>
|
|
|
|
|
#include <string>
|
2026-02-15 11:17:12 -05:00
|
|
|
|
2026-02-15 13:56:08 -05:00
|
|
|
// Internal structure wrapping rocksdb::DB
|
|
|
|
|
struct jormun_db {
|
|
|
|
|
rocksdb::DB* db;
|
|
|
|
|
};
|
2026-02-15 11:17:12 -05:00
|
|
|
|
2026-02-15 13:56:08 -05:00
|
|
|
// Placeholder for WAL iterator (not implemented yet)
|
|
|
|
|
struct jormun_wal_iter {
|
|
|
|
|
// TODO: Implement with TransactionLogIterator when needed
|
|
|
|
|
void* placeholder;
|
|
|
|
|
};
|
2026-02-15 11:17:12 -05:00
|
|
|
|
2026-02-15 13:56:08 -05:00
|
|
|
// Open database
|
|
|
|
|
jormun_db* jormun_db_open(const char* path, int create_if_missing, char** err) {
|
|
|
|
|
rocksdb::Options options;
|
|
|
|
|
options.create_if_missing = create_if_missing != 0;
|
|
|
|
|
|
|
|
|
|
rocksdb::DB* db_ptr = nullptr;
|
|
|
|
|
rocksdb::Status status = rocksdb::DB::Open(options, path, &db_ptr);
|
|
|
|
|
|
|
|
|
|
if (!status.ok()) {
|
|
|
|
|
if (err) {
|
|
|
|
|
std::string error_msg = status.ToString();
|
|
|
|
|
*err = strdup(error_msg.c_str());
|
|
|
|
|
}
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
jormun_db* jdb = new jormun_db;
|
|
|
|
|
jdb->db = db_ptr;
|
|
|
|
|
return jdb;
|
|
|
|
|
}
|
2026-02-15 11:17:12 -05:00
|
|
|
|
2026-02-15 13:56:08 -05:00
|
|
|
// Close database
|
|
|
|
|
void jormun_db_close(jormun_db* db) {
|
|
|
|
|
if (db) {
|
|
|
|
|
delete db->db;
|
|
|
|
|
delete db;
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-02-15 11:17:12 -05:00
|
|
|
|
2026-02-15 13:56:08 -05:00
|
|
|
// Put key-value pair
|
|
|
|
|
void jormun_db_put(jormun_db* db,
|
|
|
|
|
const void* key, size_t keylen,
|
|
|
|
|
const void* val, size_t vallen,
|
|
|
|
|
char** err) {
|
|
|
|
|
if (!db || !db->db) {
|
|
|
|
|
if (err) *err = strdup("Database is null");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rocksdb::WriteOptions write_options;
|
|
|
|
|
rocksdb::Slice key_slice(static_cast<const char*>(key), keylen);
|
|
|
|
|
rocksdb::Slice val_slice(static_cast<const char*>(val), vallen);
|
|
|
|
|
|
|
|
|
|
rocksdb::Status status = db->db->Put(write_options, key_slice, val_slice);
|
|
|
|
|
|
|
|
|
|
if (!status.ok() && err) {
|
|
|
|
|
std::string error_msg = status.ToString();
|
|
|
|
|
*err = strdup(error_msg.c_str());
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-02-15 11:17:12 -05:00
|
|
|
|
2026-02-15 13:56:08 -05:00
|
|
|
// Get value for key
|
|
|
|
|
unsigned char* jormun_db_get(jormun_db* db,
|
|
|
|
|
const void* key, size_t keylen,
|
|
|
|
|
size_t* vallen,
|
|
|
|
|
char** err) {
|
|
|
|
|
if (!db || !db->db) {
|
|
|
|
|
if (err) *err = strdup("Database is null");
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rocksdb::ReadOptions read_options;
|
|
|
|
|
rocksdb::Slice key_slice(static_cast<const char*>(key), keylen);
|
|
|
|
|
std::string value;
|
|
|
|
|
|
|
|
|
|
rocksdb::Status status = db->db->Get(read_options, key_slice, &value);
|
|
|
|
|
|
|
|
|
|
if (status.IsNotFound()) {
|
|
|
|
|
*vallen = 0;
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!status.ok()) {
|
|
|
|
|
if (err) {
|
|
|
|
|
std::string error_msg = status.ToString();
|
|
|
|
|
*err = strdup(error_msg.c_str());
|
|
|
|
|
}
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Allocate and copy value
|
|
|
|
|
*vallen = value.size();
|
|
|
|
|
unsigned char* result = static_cast<unsigned char*>(malloc(value.size()));
|
|
|
|
|
if (result) {
|
|
|
|
|
memcpy(result, value.data(), value.size());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
2026-02-15 11:17:12 -05:00
|
|
|
|
2026-02-15 13:56:08 -05:00
|
|
|
// Free memory allocated by the shim
|
|
|
|
|
void jormun_free(void* p) {
|
|
|
|
|
free(p);
|
|
|
|
|
}
|
2026-02-15 11:17:12 -05:00
|
|
|
|
2026-02-15 13:56:08 -05:00
|
|
|
// ============================================================================
|
|
|
|
|
// WAL Replication Functions (Stubs for now - to be implemented)
|
|
|
|
|
// ============================================================================
|
2026-02-15 11:17:12 -05:00
|
|
|
|
2026-02-15 13:56:08 -05:00
|
|
|
// Get latest sequence number
|
|
|
|
|
uint64_t jormun_latest_sequence(jormun_db* db) {
|
|
|
|
|
if (!db || !db->db) return 0;
|
|
|
|
|
return db->db->GetLatestSequenceNumber();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Create WAL iterator (stub)
|
|
|
|
|
jormun_wal_iter* jormun_wal_iter_create(jormun_db* db, uint64_t seq, char** err) {
|
|
|
|
|
(void)db;
|
|
|
|
|
(void)seq;
|
|
|
|
|
if (err) {
|
|
|
|
|
*err = strdup("WAL iteration not yet implemented");
|
|
|
|
|
}
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Destroy WAL iterator (stub)
|
|
|
|
|
void jormun_wal_iter_destroy(jormun_wal_iter* it) {
|
|
|
|
|
if (it) {
|
|
|
|
|
delete it;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Get next batch from WAL (stub)
|
|
|
|
|
int jormun_wal_iter_next(jormun_wal_iter* it,
|
|
|
|
|
uint64_t* batch_start_seq,
|
|
|
|
|
unsigned char** out_data,
|
|
|
|
|
size_t* out_len,
|
|
|
|
|
char** err) {
|
|
|
|
|
(void)it;
|
|
|
|
|
(void)batch_start_seq;
|
|
|
|
|
(void)out_data;
|
|
|
|
|
(void)out_len;
|
|
|
|
|
if (err) {
|
|
|
|
|
*err = strdup("WAL iteration not yet implemented");
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Apply write batch (stub)
|
|
|
|
|
void jormun_apply_writebatch(jormun_db* db,
|
|
|
|
|
const unsigned char* data, size_t len,
|
|
|
|
|
char** err) {
|
|
|
|
|
(void)db;
|
|
|
|
|
(void)data;
|
|
|
|
|
(void)len;
|
|
|
|
|
if (err) {
|
|
|
|
|
*err = strdup("WAL apply not yet implemented");
|
|
|
|
|
}
|
|
|
|
|
}
|