Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion src/tidesdb.lua
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ ffi.cdef[[
int tidesdb_create_column_family(void* db, const char* name, tidesdb_column_family_config_t* config);
int tidesdb_drop_column_family(void* db, const char* name);
int tidesdb_rename_column_family(void* db, const char* old_name, const char* new_name);
int tidesdb_clone_column_family(void* db, const char* source_name, const char* dest_name);
void* tidesdb_get_column_family(void* db, const char* name);
int tidesdb_list_column_families(void* db, char*** names, int* count);

Expand All @@ -129,6 +130,7 @@ ffi.cdef[[
int tidesdb_txn_commit(void* txn);
int tidesdb_txn_rollback(void* txn);
void tidesdb_txn_free(void* txn);
int tidesdb_txn_reset(void* txn, int isolation);
int tidesdb_txn_savepoint(void* txn, const char* name);
int tidesdb_txn_rollback_to_savepoint(void* txn, const char* name);
int tidesdb_txn_release_savepoint(void* txn, const char* name);
Expand Down Expand Up @@ -703,6 +705,16 @@ function Transaction:rollback()
check_result(result, "failed to rollback transaction")
end

function Transaction:reset(isolation)
if self._closed then
error(TidesDBError.new("Transaction is closed"))
end

local result = lib.tidesdb_txn_reset(self._txn, isolation)
check_result(result, "failed to reset transaction")
self._committed = false
end

function Transaction:savepoint(name)
if self._closed then
error(TidesDBError.new("Transaction is closed"))
Expand Down Expand Up @@ -855,6 +867,15 @@ function TidesDB:rename_column_family(old_name, new_name)
check_result(result, "failed to rename column family")
end

function TidesDB:clone_column_family(source_name, dest_name)
if self._closed then
error(TidesDBError.new("Database is closed"))
end

local result = lib.tidesdb_clone_column_family(self._db, source_name, dest_name)
check_result(result, "failed to clone column family")
end

function TidesDB:get_column_family(name)
if self._closed then
error(TidesDBError.new("Database is closed"))
Expand Down Expand Up @@ -1011,6 +1032,6 @@ function tidesdb.save_config_to_ini(ini_file, section_name, config)
end

-- Version
tidesdb._VERSION = "0.3.0"
tidesdb._VERSION = "0.5.0"

return tidesdb
107 changes: 107 additions & 0 deletions tests/test_tidesdb.lua
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,113 @@ function tests.test_btree_stats_extended()
print("PASS: test_btree_stats_extended")
end

function tests.test_clone_column_family()
local path = "./test_db_clone_cf"
cleanup_db(path)

local db = tidesdb.TidesDB.open(path)
db:create_column_family("source_cf")
local cf = db:get_column_family("source_cf")

-- Insert data into source
local txn = db:begin_txn()
txn:put(cf, "key1", "value1")
txn:put(cf, "key2", "value2")
txn:commit()
txn:free()

-- Clone column family
db:clone_column_family("source_cf", "cloned_cf")

-- Verify cloned column family exists
local cloned_cf = db:get_column_family("cloned_cf")
assert_true(cloned_cf ~= nil, "cloned column family should exist")

-- Verify data is preserved in clone
local read_txn = db:begin_txn()
local v1 = read_txn:get(cloned_cf, "key1")
local v2 = read_txn:get(cloned_cf, "key2")
assert_eq(v1, "value1", "cloned key1 should have correct value")
assert_eq(v2, "value2", "cloned key2 should have correct value")
read_txn:free()

-- Verify source still works independently
local src_txn = db:begin_txn()
local sv1 = src_txn:get(cf, "key1")
assert_eq(sv1, "value1", "source key1 should still exist")
src_txn:free()

-- Verify modifications to clone don't affect source
local write_txn = db:begin_txn()
write_txn:put(cloned_cf, "key3", "value3")
write_txn:commit()
write_txn:free()

local verify_txn = db:begin_txn()
local v3 = verify_txn:get(cloned_cf, "key3")
assert_eq(v3, "value3", "key3 should exist in clone")
local err = assert_error(function()
verify_txn:get(cf, "key3")
end, "key3 should not exist in source")
verify_txn:free()

-- Verify cloning to existing name fails
local clone_err = assert_error(function()
db:clone_column_family("source_cf", "cloned_cf")
end, "cloning to existing name should fail")

db:drop_column_family("source_cf")
db:drop_column_family("cloned_cf")
db:close()
cleanup_db(path)
print("PASS: test_clone_column_family")
end

function tests.test_transaction_reset()
local path = "./test_db_txn_reset"
cleanup_db(path)

local db = tidesdb.TidesDB.open(path)
db:create_column_family("test_cf")
local cf = db:get_column_family("test_cf")

-- Begin transaction and do first batch of work
local txn = db:begin_txn()
txn:put(cf, "key1", "value1")
txn:commit()

-- Reset transaction instead of free + begin
txn:reset(tidesdb.IsolationLevel.READ_COMMITTED)

-- Second batch of work using the same transaction
txn:put(cf, "key2", "value2")
txn:commit()

-- Reset again with different isolation level
txn:reset(tidesdb.IsolationLevel.SERIALIZABLE)

-- Third batch
txn:put(cf, "key3", "value3")
txn:commit()

txn:free()

-- Verify all data was written
local read_txn = db:begin_txn()
local v1 = read_txn:get(cf, "key1")
local v2 = read_txn:get(cf, "key2")
local v3 = read_txn:get(cf, "key3")
assert_eq(v1, "value1", "key1 should exist after reset")
assert_eq(v2, "value2", "key2 should exist after reset")
assert_eq(v3, "value3", "key3 should exist after reset")
read_txn:free()

db:drop_column_family("test_cf")
db:close()
cleanup_db(path)
print("PASS: test_transaction_reset")
end

-- Run all tests
local function run_tests()
print("Running TidesDB Lua tests...")
Expand Down
4 changes: 2 additions & 2 deletions tidesdb-0.4.0-1.rockspec → tidesdb-0.5.0-1.rockspec
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package = "tidesdb"
version = "0.4.0-1"
version = "0.5.0-1"
source = {
url = "git://github.com/tidesdb/tidesdb-lua.git",
tag = "v0.4.0"
tag = "v0.5.0"
}
description = {
summary = "Official Lua bindings for TidesDB - A high-performance embedded key-value storage engine",
Expand Down
Loading