should be it
This commit is contained in:
159
external/duckdb/test/api/capi/capi_file_system.cpp
vendored
Normal file
159
external/duckdb/test/api/capi/capi_file_system.cpp
vendored
Normal 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);
|
||||
}
|
||||
Reference in New Issue
Block a user