diff --git a/Sources/Bodega/SQLiteStorageEngine.swift b/Sources/Bodega/SQLiteStorageEngine.swift index 31069e6..be7ac00 100644 --- a/Sources/Bodega/SQLiteStorageEngine.swift +++ b/Sources/Bodega/SQLiteStorageEngine.swift @@ -211,6 +211,7 @@ public actor SQLiteStorageEngine: StorageEngine { /// Removes all the `Data` items from the database. public func removeAllData() throws { try self.connection.run(Self.storageTable.delete()) + let _ = try? self.connection.vacuum() } /// Checks whether a value with a key is persisted. diff --git a/Tests/BodegaTests/SQLiteStorageEngineTests.swift b/Tests/BodegaTests/SQLiteStorageEngineTests.swift index 3b10740..bb11e65 100644 --- a/Tests/BodegaTests/SQLiteStorageEngineTests.swift +++ b/Tests/BodegaTests/SQLiteStorageEngineTests.swift @@ -195,6 +195,25 @@ final class SQLiteStorageEngineTests: XCTestCase { XCTAssertEqual(updatedKeyCount, 0) } + func testVacuumAfterRemoveAllData() async throws { + let directory: FileManager.Directory = .temporary(appendingPath: "VacuumTests") + let otherStorage = SQLiteStorageEngine(directory: directory, databaseFilename: "data")! + + for i in 0 ..< 100 { + // This encoding could fail in some use cases but we're going to use very simple strings for testing + try await otherStorage.write("Value \(i)".data(using: .utf8)!, key: CacheKey(verbatim: "\(i)")) + } + + let filledDatabaseSize: Int = try directory.url.appendingPathComponent("data").appendingPathExtension("sqlite3").resourceValues(forKeys: [.fileSizeKey]).fileSize ?? 0 + + try await otherStorage.removeAllData() + + let emptyDatabaseSize: Int = try directory.url.appendingPathComponent("data").appendingPathExtension("sqlite3").resourceValues(forKeys: [.fileSizeKey]).fileSize ?? 0 + + // check that the sqlite3 file decreased in size after calling removeAllData, meaning that vacuum-ing the database works + XCTAssertLessThan(emptyDatabaseSize, filledDatabaseSize) + } + func testRemovingNonExistentObjectDoesNotError() async throws { try await storage.write(Self.testData, key: Self.testCacheKey) try await storage.remove(key: CacheKey(verbatim: "alternative-test-key"))