should be it

This commit is contained in:
2025-10-24 19:21:19 -05:00
parent a4b23fc57c
commit f09560c7b1
14047 changed files with 3161551 additions and 1 deletions

View File

@@ -0,0 +1,159 @@
#include "capi_tester.hpp"
using namespace duckdb;
using namespace std;
static void test_file_system(duckdb_file_system fs, string file_name) {
REQUIRE(fs != nullptr);
duckdb_state state = DuckDBSuccess;
duckdb_file_handle file;
auto file_path = TestDirectoryPath() + "/" + file_name;
auto options = duckdb_create_file_open_options();
state = duckdb_file_open_options_set_flag(options, DUCKDB_FILE_FLAG_WRITE, true);
REQUIRE(state == DuckDBSuccess);
state = duckdb_file_open_options_set_flag(options, DUCKDB_FILE_FLAG_READ, true);
REQUIRE(state == DuckDBSuccess);
// Try to open non-existing file without create flag
state = duckdb_file_system_open(fs, file_path.c_str(), options, &file);
REQUIRE(state != DuckDBSuccess);
auto error_data = duckdb_file_system_error_data(fs);
auto error_type = duckdb_error_data_error_type(error_data);
REQUIRE(error_type == DUCKDB_ERROR_IO);
duckdb_destroy_error_data(&error_data);
// Try to write to a null file handle
auto failed_bytes_written = duckdb_file_handle_write(file, "data", 4);
REQUIRE(failed_bytes_written == -1);
auto file_error_data = duckdb_file_handle_error_data(file);
auto has_error = duckdb_error_data_has_error(file_error_data);
REQUIRE(has_error == false);
duckdb_destroy_error_data(&file_error_data);
// Set create flag
state = duckdb_file_open_options_set_flag(options, DUCKDB_FILE_FLAG_CREATE, true);
REQUIRE(state == DuckDBSuccess);
// Create and open a file
state = duckdb_file_system_open(fs, file_path.c_str(), options, &file);
REQUIRE(state == DuckDBSuccess);
REQUIRE(file != nullptr);
// Write to the file
const char *data = "Hello, DuckDB File System!";
auto bytes_written = duckdb_file_handle_write(file, data, strlen(data));
REQUIRE(bytes_written == (int64_t)strlen(data));
auto position = duckdb_file_handle_tell(file);
REQUIRE(position == bytes_written);
auto size = duckdb_file_handle_size(file);
REQUIRE(size == bytes_written);
// Sync
state = duckdb_file_handle_sync(file);
// Seek to the beginning
state = duckdb_file_handle_seek(file, 0);
REQUIRE(state == DuckDBSuccess);
position = duckdb_file_handle_tell(file);
REQUIRE(position == 0);
// Read from the file
char buffer[30];
memset(buffer, 0, sizeof(buffer));
auto bytes_read = duckdb_file_handle_read(file, buffer, sizeof(buffer) - 1);
REQUIRE(bytes_read == bytes_written);
REQUIRE(strcmp(buffer, data) == 0);
position = duckdb_file_handle_tell(file);
REQUIRE(position == bytes_read);
size = duckdb_file_handle_size(file);
REQUIRE(size == bytes_written);
// Seek to the end
state = duckdb_file_handle_seek(file, bytes_written);
REQUIRE(state == DuckDBSuccess);
position = duckdb_file_handle_tell(file);
REQUIRE(position == bytes_written);
size = duckdb_file_handle_size(file);
REQUIRE(size == bytes_written);
// Try to read from the end of the file
memset(buffer, 0, sizeof(buffer));
bytes_read = duckdb_file_handle_read(file, buffer, sizeof(buffer) - 1);
REQUIRE(bytes_read == 0); // EOF
position = duckdb_file_handle_tell(file);
REQUIRE(position == bytes_written);
size = duckdb_file_handle_size(file);
REQUIRE(size == bytes_written);
// Seek back to the beginning
state = duckdb_file_handle_seek(file, 0);
REQUIRE(state == DuckDBSuccess);
position = duckdb_file_handle_tell(file);
REQUIRE(position == 0);
size = duckdb_file_handle_size(file);
REQUIRE(size == bytes_written);
// Close the file
duckdb_file_handle_close(file);
duckdb_destroy_file_handle(&file);
// Open file again for reading
state = duckdb_file_system_open(fs, file_path.c_str(), options, &file);
REQUIRE(state == DuckDBSuccess);
REQUIRE(file != nullptr);
size = duckdb_file_handle_size(file);
REQUIRE(size == bytes_written);
// Check that the data is still there
memset(buffer, 0, sizeof(buffer));
bytes_read = duckdb_file_handle_read(file, buffer, sizeof(buffer) - 1);
REQUIRE(bytes_read == bytes_written);
REQUIRE(strcmp(buffer, data) == 0);
position = duckdb_file_handle_tell(file);
REQUIRE(position == bytes_read);
size = duckdb_file_handle_size(file);
REQUIRE(size == bytes_written);
// Close the file again
duckdb_file_handle_close(file);
duckdb_destroy_file_handle(&file);
duckdb_destroy_file_open_options(&options);
REQUIRE(file == nullptr);
REQUIRE(options == nullptr);
// Try destroy again for good measure
duckdb_destroy_file_handle(&file);
duckdb_destroy_file_open_options(&options);
REQUIRE(file == nullptr);
REQUIRE(options == nullptr);
}
TEST_CASE("Test File System in C API", "[capi]") {
CAPITester tester;
duckdb_client_context context;
duckdb_file_system fs;
duckdb::unique_ptr<CAPIResult> result;
REQUIRE(tester.OpenDatabase(nullptr));
// get a file system from the client context
duckdb_connection_get_client_context(tester.connection, &context);
fs = duckdb_client_context_get_file_system(context);
REQUIRE(fs != nullptr);
test_file_system(fs, "test_file_capi_1.txt");
duckdb_destroy_file_system(&fs);
REQUIRE(fs == nullptr);
duckdb_destroy_client_context(&context);
// Try to destory fs again
duckdb_destroy_file_system(&fs);
REQUIRE(fs == nullptr);
}