diff --git a/Tests/LibSQL/TestSqlDatabase.cpp b/Tests/LibSQL/TestSqlDatabase.cpp index f5738af391..6bf563771e 100644 --- a/Tests/LibSQL/TestSqlDatabase.cpp +++ b/Tests/LibSQL/TestSqlDatabase.cpp @@ -206,3 +206,32 @@ TEST_CASE(insert_100_into_table) { insert_and_verify(100); } + +TEST_CASE(reuse_row_storage) +{ + ScopeGuard guard([]() { unlink("/tmp/test.db"); }); + auto db = SQL::Database::construct("/tmp/test.db"); + MUST(db->open()); + (void)setup_table(db); + auto table = MUST(db->get_table("TestSchema", "TestTable")); + + // Insert row + SQL::Row row(*table); + row["TextColumn"] = "text value"; + row["IntColumn"] = 12345; + TRY_OR_FAIL(db->insert(row)); + TRY_OR_FAIL(db->commit()); + auto original_size_in_bytes = MUST(db->file_size_in_bytes()); + + // Remove row + TRY_OR_FAIL(db->remove(row)); + TRY_OR_FAIL(db->commit()); + auto size_in_bytes_after_removal = MUST(db->file_size_in_bytes()); + EXPECT(size_in_bytes_after_removal <= original_size_in_bytes); + + // Insert same row again + TRY_OR_FAIL(db->insert(row)); + TRY_OR_FAIL(db->commit()); + auto size_in_bytes_after_reinsertion = MUST(db->file_size_in_bytes()); + EXPECT(size_in_bytes_after_reinsertion <= original_size_in_bytes); +} diff --git a/Userland/Libraries/LibSQL/Database.cpp b/Userland/Libraries/LibSQL/Database.cpp index 25f1431e14..37a1ddb423 100644 --- a/Userland/Libraries/LibSQL/Database.cpp +++ b/Userland/Libraries/LibSQL/Database.cpp @@ -6,7 +6,6 @@ */ #include -#include #include #include #include @@ -217,6 +216,8 @@ ErrorOr Database::remove(Row& row) auto& table = row.table(); VERIFY(m_table_cache.get(table.key().hash()).has_value()); + TRY(m_heap->free_storage(row.block_index())); + if (table.block_index() == row.block_index()) { auto table_key = table.key(); table_key.set_block_index(row.next_block_index()); diff --git a/Userland/Libraries/LibSQL/Database.h b/Userland/Libraries/LibSQL/Database.h index a9d1179aef..14b048dc1c 100644 --- a/Userland/Libraries/LibSQL/Database.h +++ b/Userland/Libraries/LibSQL/Database.h @@ -8,6 +8,7 @@ #pragma once #include +#include #include #include #include @@ -32,6 +33,7 @@ public: ResultOr open(); bool is_open() const { return m_open; } ErrorOr commit(); + ErrorOr file_size_in_bytes() const { return m_heap->file_size_in_bytes(); } ResultOr add_schema(SchemaDef const&); static Key get_schema_key(DeprecatedString const&);