diff --git a/adbc.h b/adbc.h index 3e2d0f92d2..122b0605ae 100644 --- a/adbc.h +++ b/adbc.h @@ -902,8 +902,8 @@ struct ADBC_EXPORT AdbcDriver { AdbcStatusCode (*ConnectionCancel)(struct AdbcConnection*, struct AdbcError*); AdbcStatusCode (*ConnectionGetOption)(struct AdbcConnection*, const char*, char*, size_t*, struct AdbcError*); - AdbcStatusCode (*ConnectionGetOptionBytes)(struct AdbcDatabase*, const char*, uint8_t*, - size_t*, struct AdbcError*); + AdbcStatusCode (*ConnectionGetOptionBytes)(struct AdbcConnection*, const char*, + uint8_t*, size_t*, struct AdbcError*); AdbcStatusCode (*ConnectionGetOptionInt)(struct AdbcConnection*, const char*, int64_t*, struct AdbcError*); AdbcStatusCode (*ConnectionGetOptionDouble)(struct AdbcConnection*, const char*, @@ -914,7 +914,7 @@ struct ADBC_EXPORT AdbcDriver { AdbcStatusCode (*ConnectionGetStatisticNames)(struct AdbcConnection*, struct ArrowArrayStream*, struct AdbcError*); - AdbcStatusCode (*ConnectionSetOptionBytes)(struct AdbcDatabase*, const char*, + AdbcStatusCode (*ConnectionSetOptionBytes)(struct AdbcConnection*, const char*, const uint8_t*, size_t, struct AdbcError*); AdbcStatusCode (*ConnectionSetOptionInt)(struct AdbcConnection*, const char*, int64_t, struct AdbcError*); @@ -926,13 +926,13 @@ struct ADBC_EXPORT AdbcDriver { struct AdbcError*); AdbcStatusCode (*StatementGetOption)(struct AdbcStatement*, const char*, char*, size_t*, struct AdbcError*); - AdbcStatusCode (*StatementGetOptionBytes)(struct AdbcDatabase*, const char*, uint8_t*, + AdbcStatusCode (*StatementGetOptionBytes)(struct AdbcStatement*, const char*, uint8_t*, size_t*, struct AdbcError*); AdbcStatusCode (*StatementGetOptionInt)(struct AdbcStatement*, const char*, int64_t*, struct AdbcError*); AdbcStatusCode (*StatementGetOptionDouble)(struct AdbcStatement*, const char*, double*, struct AdbcError*); - AdbcStatusCode (*StatementSetOptionBytes)(struct AdbcDatabase*, const char*, + AdbcStatusCode (*StatementSetOptionBytes)(struct AdbcStatement*, const char*, const uint8_t*, size_t, struct AdbcError*); AdbcStatusCode (*StatementSetOptionInt)(struct AdbcStatement*, const char*, int64_t, struct AdbcError*); diff --git a/c/driver_manager/adbc_driver_manager.cc b/c/driver_manager/adbc_driver_manager.cc index 8486bf1a55..380ceb41bf 100644 --- a/c/driver_manager/adbc_driver_manager.cc +++ b/c/driver_manager/adbc_driver_manager.cc @@ -135,6 +135,12 @@ AdbcStatusCode DatabaseGetOption(struct AdbcDatabase* database, const char* key, return ADBC_STATUS_NOT_IMPLEMENTED; } +AdbcStatusCode DatabaseGetOptionBytes(struct AdbcDatabase* database, const char* key, + uint8_t* value, size_t* length, + struct AdbcError* error) { + return ADBC_STATUS_NOT_IMPLEMENTED; +} + AdbcStatusCode DatabaseGetOptionInt(struct AdbcDatabase* database, const char* key, int64_t* value, struct AdbcError* error) { return ADBC_STATUS_NOT_IMPLEMENTED; @@ -150,6 +156,12 @@ AdbcStatusCode DatabaseSetOption(struct AdbcDatabase* database, const char* key, return ADBC_STATUS_NOT_IMPLEMENTED; } +AdbcStatusCode DatabaseSetOptionBytes(struct AdbcDatabase* database, const char* key, + const uint8_t* value, size_t length, + struct AdbcError* error) { + return ADBC_STATUS_NOT_IMPLEMENTED; +} + AdbcStatusCode DatabaseSetOptionInt(struct AdbcDatabase* database, const char* key, int64_t value, struct AdbcError* error) { return ADBC_STATUS_NOT_IMPLEMENTED; @@ -186,6 +198,12 @@ AdbcStatusCode ConnectionGetOption(struct AdbcConnection* connection, const char return ADBC_STATUS_NOT_IMPLEMENTED; } +AdbcStatusCode ConnectionGetOptionBytes(struct AdbcConnection* connection, + const char* key, uint8_t* value, size_t* length, + struct AdbcError* error) { + return ADBC_STATUS_NOT_IMPLEMENTED; +} + AdbcStatusCode ConnectionGetOptionInt(struct AdbcConnection* connection, const char* key, int64_t* value, struct AdbcError* error) { return ADBC_STATUS_NOT_IMPLEMENTED; @@ -225,6 +243,11 @@ AdbcStatusCode ConnectionSetOption(struct AdbcConnection*, const char*, const ch return ADBC_STATUS_NOT_IMPLEMENTED; } +AdbcStatusCode ConnectionSetOptionBytes(struct AdbcConnection*, const char*, + const uint8_t*, size_t, struct AdbcError* error) { + return ADBC_STATUS_NOT_IMPLEMENTED; +} + AdbcStatusCode ConnectionSetOptionInt(struct AdbcConnection* connection, const char* key, int64_t value, struct AdbcError* error) { return ADBC_STATUS_NOT_IMPLEMENTED; @@ -264,6 +287,12 @@ AdbcStatusCode StatementGetOption(struct AdbcStatement* statement, const char* k return ADBC_STATUS_NOT_IMPLEMENTED; } +AdbcStatusCode StatementGetOptionBytes(struct AdbcStatement* statement, const char* key, + uint8_t* value, size_t* length, + struct AdbcError* error) { + return ADBC_STATUS_NOT_IMPLEMENTED; +} + AdbcStatusCode StatementGetOptionInt(struct AdbcStatement* statement, const char* key, int64_t* value, struct AdbcError* error) { return ADBC_STATUS_NOT_IMPLEMENTED; @@ -289,6 +318,11 @@ AdbcStatusCode StatementSetOption(struct AdbcStatement*, const char*, const char return ADBC_STATUS_NOT_IMPLEMENTED; } +AdbcStatusCode StatementSetOptionBytes(struct AdbcStatement*, const char*, const uint8_t*, + size_t, struct AdbcError* error) { + return ADBC_STATUS_NOT_IMPLEMENTED; +} + AdbcStatusCode StatementSetOptionInt(struct AdbcStatement* statement, const char* key, int64_t value, struct AdbcError* error) { return ADBC_STATUS_NOT_IMPLEMENTED; @@ -312,6 +346,7 @@ AdbcStatusCode StatementSetSubstraitPlan(struct AdbcStatement*, const uint8_t*, /// Temporary state while the database is being configured. struct TempDatabase { std::unordered_map options; + std::unordered_map bytes_options; std::unordered_map int_options; std::unordered_map double_options; std::string driver; @@ -323,6 +358,7 @@ struct TempDatabase { /// Temporary state while the database is being configured. struct TempConnection { std::unordered_map options; + std::unordered_map bytes_options; std::unordered_map int_options; std::unordered_map double_options; }; @@ -366,6 +402,28 @@ AdbcStatusCode AdbcDatabaseGetOption(struct AdbcDatabase* database, const char* return ADBC_STATUS_OK; } +AdbcStatusCode AdbcDatabaseGetOptionBytes(struct AdbcDatabase* database, const char* key, + uint8_t* value, size_t* length, + struct AdbcError* error) { + if (database->private_driver) { + return database->private_driver->DatabaseGetOptionBytes(database, key, value, length, + error); + } + const auto* args = reinterpret_cast(database->private_data); + const auto it = args->bytes_options.find(key); + if (it == args->options.end()) { + return ADBC_STATUS_NOT_FOUND; + } + const std::string& result = it->second; + + if (*length <= result.size()) { + // Enough space + std::memcpy(value, result.c_str(), result.size()); + } + *length = result.size(); + return ADBC_STATUS_OK; +} + AdbcStatusCode AdbcDatabaseGetOptionInt(struct AdbcDatabase* database, const char* key, int64_t* value, struct AdbcError* error) { if (database->private_driver) { @@ -411,6 +469,19 @@ AdbcStatusCode AdbcDatabaseSetOption(struct AdbcDatabase* database, const char* return ADBC_STATUS_OK; } +AdbcStatusCode AdbcDatabaseSetOptionBytes(struct AdbcDatabase* database, const char* key, + const uint8_t* value, size_t length, + struct AdbcError* error) { + if (database->private_driver) { + return database->private_driver->DatabaseSetOptionBytes(database, key, value, length, + error); + } + + TempDatabase* args = reinterpret_cast(database->private_data); + args->bytes_options[key] = std::string(reinterpret_cast(value), length); + return ADBC_STATUS_OK; +} + AdbcStatusCode AdbcDatabaseSetOptionInt(struct AdbcDatabase* database, const char* key, int64_t value, struct AdbcError* error) { if (database->private_driver) { @@ -490,6 +561,7 @@ AdbcStatusCode AdbcDatabaseInit(struct AdbcDatabase* database, struct AdbcError* return status; } auto options = std::move(args->options); + auto bytes_options = std::move(args->bytes_options); auto int_options = std::move(args->int_options); auto double_options = std::move(args->double_options); delete args; @@ -499,6 +571,13 @@ AdbcStatusCode AdbcDatabaseInit(struct AdbcDatabase* database, struct AdbcError* option.second.c_str(), error); if (status != ADBC_STATUS_OK) break; } + for (const auto& option : bytes_options) { + status = database->private_driver->DatabaseSetOptionBytes( + database, option.first.c_str(), + reinterpret_cast(option.second.data()), option.second.size(), + error); + if (status != ADBC_STATUS_OK) break; + } for (const auto& option : int_options) { status = database->private_driver->DatabaseSetOptionInt( database, option.first.c_str(), option.second, error); @@ -612,6 +691,30 @@ AdbcStatusCode AdbcConnectionGetOption(struct AdbcConnection* connection, const error); } +AdbcStatusCode AdbcConnectionGetOptionBytes(struct AdbcConnection* connection, + const char* key, uint8_t* value, + size_t* length, struct AdbcError* error) { + if (!connection->private_data) { + SetError(error, "AdbcConnectionGetOption: must AdbcConnectionNew first"); + return ADBC_STATUS_INVALID_STATE; + } + if (!connection->private_driver) { + // Init not yet called, get the saved option + const auto* args = reinterpret_cast(connection->private_data); + const auto it = args->bytes_options.find(key); + if (it == args->options.end()) { + return ADBC_STATUS_NOT_FOUND; + } + if (*length >= it->second.size() + 1) { + std::memcpy(value, it->second.data(), it->second.size() + 1); + } + *length = it->second.size() + 1; + return ADBC_STATUS_OK; + } + return connection->private_driver->ConnectionGetOptionBytes(connection, key, value, + length, error); +} + AdbcStatusCode AdbcConnectionGetOptionInt(struct AdbcConnection* connection, const char* key, int64_t* value, struct AdbcError* error) { @@ -688,6 +791,8 @@ AdbcStatusCode AdbcConnectionInit(struct AdbcConnection* connection, TempConnection* args = reinterpret_cast(connection->private_data); connection->private_data = nullptr; std::unordered_map options = std::move(args->options); + std::unordered_map bytes_options = + std::move(args->bytes_options); std::unordered_map int_options = std::move(args->int_options); std::unordered_map double_options = std::move(args->double_options); @@ -702,6 +807,13 @@ AdbcStatusCode AdbcConnectionInit(struct AdbcConnection* connection, connection, option.first.c_str(), option.second.c_str(), error); if (status != ADBC_STATUS_OK) return status; } + for (const auto& option : bytes_options) { + status = database->private_driver->ConnectionSetOptionBytes( + connection, option.first.c_str(), + reinterpret_cast(option.second.data()), option.second.size(), + error); + if (status != ADBC_STATUS_OK) return status; + } for (const auto& option : int_options) { status = database->private_driver->ConnectionSetOptionInt( connection, option.first.c_str(), option.second, error); @@ -776,6 +888,23 @@ AdbcStatusCode AdbcConnectionSetOption(struct AdbcConnection* connection, const return connection->private_driver->ConnectionSetOption(connection, key, value, error); } +AdbcStatusCode AdbcConnectionSetOptionBytes(struct AdbcConnection* connection, + const char* key, const uint8_t* value, + size_t length, struct AdbcError* error) { + if (!connection->private_data) { + SetError(error, "AdbcConnectionSetOptionInt: must AdbcConnectionNew first"); + return ADBC_STATUS_INVALID_STATE; + } + if (!connection->private_driver) { + // Init not yet called, save the option + TempConnection* args = reinterpret_cast(connection->private_data); + args->bytes_options[key] = std::string(reinterpret_cast(value), length); + return ADBC_STATUS_OK; + } + return connection->private_driver->ConnectionSetOptionBytes(connection, key, value, + length, error); +} + AdbcStatusCode AdbcConnectionSetOptionInt(struct AdbcConnection* connection, const char* key, int64_t value, struct AdbcError* error) { @@ -879,6 +1008,16 @@ AdbcStatusCode AdbcStatementGetOption(struct AdbcStatement* statement, const cha error); } +AdbcStatusCode AdbcStatementGetOptionBytes(struct AdbcStatement* statement, + const char* key, uint8_t* value, + size_t* length, struct AdbcError* error) { + if (!statement->private_driver) { + return ADBC_STATUS_INVALID_STATE; + } + return statement->private_driver->StatementGetOptionBytes(statement, key, value, length, + error); +} + AdbcStatusCode AdbcStatementGetOptionInt(struct AdbcStatement* statement, const char* key, int64_t* value, struct AdbcError* error) { if (!statement->private_driver) { @@ -943,6 +1082,16 @@ AdbcStatusCode AdbcStatementSetOption(struct AdbcStatement* statement, const cha return statement->private_driver->StatementSetOption(statement, key, value, error); } +AdbcStatusCode AdbcStatementSetOptionBytes(struct AdbcStatement* statement, + const char* key, const uint8_t* value, + size_t length, struct AdbcError* error) { + if (!statement->private_driver) { + return ADBC_STATUS_INVALID_STATE; + } + return statement->private_driver->StatementSetOptionBytes(statement, key, value, length, + error); +} + AdbcStatusCode AdbcStatementSetOptionInt(struct AdbcStatement* statement, const char* key, int64_t value, struct AdbcError* error) { if (!statement->private_driver) { @@ -1229,23 +1378,29 @@ AdbcStatusCode AdbcLoadDriverFromInitFunc(AdbcDriverInitFunc init_func, int vers if (version >= ADBC_VERSION_1_1_0) { auto* driver = reinterpret_cast(raw_driver); FILL_DEFAULT(driver, DatabaseGetOption); + FILL_DEFAULT(driver, DatabaseGetOptionBytes); FILL_DEFAULT(driver, DatabaseGetOptionInt); FILL_DEFAULT(driver, DatabaseGetOptionDouble); + FILL_DEFAULT(driver, DatabaseSetOptionBytes); FILL_DEFAULT(driver, DatabaseSetOptionInt); FILL_DEFAULT(driver, DatabaseSetOptionDouble); FILL_DEFAULT(driver, ConnectionCancel); FILL_DEFAULT(driver, ConnectionGetOption); + FILL_DEFAULT(driver, ConnectionGetOptionBytes); FILL_DEFAULT(driver, ConnectionGetOptionInt); FILL_DEFAULT(driver, ConnectionGetOptionDouble); + FILL_DEFAULT(driver, ConnectionSetOptionBytes); FILL_DEFAULT(driver, ConnectionSetOptionInt); FILL_DEFAULT(driver, ConnectionSetOptionDouble); FILL_DEFAULT(driver, StatementCancel); FILL_DEFAULT(driver, StatementExecuteSchema); FILL_DEFAULT(driver, StatementGetOption); + FILL_DEFAULT(driver, StatementGetOptionBytes); FILL_DEFAULT(driver, StatementGetOptionInt); FILL_DEFAULT(driver, StatementGetOptionDouble); + FILL_DEFAULT(driver, StatementSetOptionBytes); FILL_DEFAULT(driver, StatementSetOptionInt); FILL_DEFAULT(driver, StatementSetOptionDouble); } diff --git a/go/adbc/drivermgr/adbc.h b/go/adbc/drivermgr/adbc.h index 3e2d0f92d2..122b0605ae 100644 --- a/go/adbc/drivermgr/adbc.h +++ b/go/adbc/drivermgr/adbc.h @@ -902,8 +902,8 @@ struct ADBC_EXPORT AdbcDriver { AdbcStatusCode (*ConnectionCancel)(struct AdbcConnection*, struct AdbcError*); AdbcStatusCode (*ConnectionGetOption)(struct AdbcConnection*, const char*, char*, size_t*, struct AdbcError*); - AdbcStatusCode (*ConnectionGetOptionBytes)(struct AdbcDatabase*, const char*, uint8_t*, - size_t*, struct AdbcError*); + AdbcStatusCode (*ConnectionGetOptionBytes)(struct AdbcConnection*, const char*, + uint8_t*, size_t*, struct AdbcError*); AdbcStatusCode (*ConnectionGetOptionInt)(struct AdbcConnection*, const char*, int64_t*, struct AdbcError*); AdbcStatusCode (*ConnectionGetOptionDouble)(struct AdbcConnection*, const char*, @@ -914,7 +914,7 @@ struct ADBC_EXPORT AdbcDriver { AdbcStatusCode (*ConnectionGetStatisticNames)(struct AdbcConnection*, struct ArrowArrayStream*, struct AdbcError*); - AdbcStatusCode (*ConnectionSetOptionBytes)(struct AdbcDatabase*, const char*, + AdbcStatusCode (*ConnectionSetOptionBytes)(struct AdbcConnection*, const char*, const uint8_t*, size_t, struct AdbcError*); AdbcStatusCode (*ConnectionSetOptionInt)(struct AdbcConnection*, const char*, int64_t, struct AdbcError*); @@ -926,13 +926,13 @@ struct ADBC_EXPORT AdbcDriver { struct AdbcError*); AdbcStatusCode (*StatementGetOption)(struct AdbcStatement*, const char*, char*, size_t*, struct AdbcError*); - AdbcStatusCode (*StatementGetOptionBytes)(struct AdbcDatabase*, const char*, uint8_t*, + AdbcStatusCode (*StatementGetOptionBytes)(struct AdbcStatement*, const char*, uint8_t*, size_t*, struct AdbcError*); AdbcStatusCode (*StatementGetOptionInt)(struct AdbcStatement*, const char*, int64_t*, struct AdbcError*); AdbcStatusCode (*StatementGetOptionDouble)(struct AdbcStatement*, const char*, double*, struct AdbcError*); - AdbcStatusCode (*StatementSetOptionBytes)(struct AdbcDatabase*, const char*, + AdbcStatusCode (*StatementSetOptionBytes)(struct AdbcStatement*, const char*, const uint8_t*, size_t, struct AdbcError*); AdbcStatusCode (*StatementSetOptionInt)(struct AdbcStatement*, const char*, int64_t, struct AdbcError*); diff --git a/go/adbc/drivermgr/adbc_driver_manager.cc b/go/adbc/drivermgr/adbc_driver_manager.cc index 8486bf1a55..380ceb41bf 100644 --- a/go/adbc/drivermgr/adbc_driver_manager.cc +++ b/go/adbc/drivermgr/adbc_driver_manager.cc @@ -135,6 +135,12 @@ AdbcStatusCode DatabaseGetOption(struct AdbcDatabase* database, const char* key, return ADBC_STATUS_NOT_IMPLEMENTED; } +AdbcStatusCode DatabaseGetOptionBytes(struct AdbcDatabase* database, const char* key, + uint8_t* value, size_t* length, + struct AdbcError* error) { + return ADBC_STATUS_NOT_IMPLEMENTED; +} + AdbcStatusCode DatabaseGetOptionInt(struct AdbcDatabase* database, const char* key, int64_t* value, struct AdbcError* error) { return ADBC_STATUS_NOT_IMPLEMENTED; @@ -150,6 +156,12 @@ AdbcStatusCode DatabaseSetOption(struct AdbcDatabase* database, const char* key, return ADBC_STATUS_NOT_IMPLEMENTED; } +AdbcStatusCode DatabaseSetOptionBytes(struct AdbcDatabase* database, const char* key, + const uint8_t* value, size_t length, + struct AdbcError* error) { + return ADBC_STATUS_NOT_IMPLEMENTED; +} + AdbcStatusCode DatabaseSetOptionInt(struct AdbcDatabase* database, const char* key, int64_t value, struct AdbcError* error) { return ADBC_STATUS_NOT_IMPLEMENTED; @@ -186,6 +198,12 @@ AdbcStatusCode ConnectionGetOption(struct AdbcConnection* connection, const char return ADBC_STATUS_NOT_IMPLEMENTED; } +AdbcStatusCode ConnectionGetOptionBytes(struct AdbcConnection* connection, + const char* key, uint8_t* value, size_t* length, + struct AdbcError* error) { + return ADBC_STATUS_NOT_IMPLEMENTED; +} + AdbcStatusCode ConnectionGetOptionInt(struct AdbcConnection* connection, const char* key, int64_t* value, struct AdbcError* error) { return ADBC_STATUS_NOT_IMPLEMENTED; @@ -225,6 +243,11 @@ AdbcStatusCode ConnectionSetOption(struct AdbcConnection*, const char*, const ch return ADBC_STATUS_NOT_IMPLEMENTED; } +AdbcStatusCode ConnectionSetOptionBytes(struct AdbcConnection*, const char*, + const uint8_t*, size_t, struct AdbcError* error) { + return ADBC_STATUS_NOT_IMPLEMENTED; +} + AdbcStatusCode ConnectionSetOptionInt(struct AdbcConnection* connection, const char* key, int64_t value, struct AdbcError* error) { return ADBC_STATUS_NOT_IMPLEMENTED; @@ -264,6 +287,12 @@ AdbcStatusCode StatementGetOption(struct AdbcStatement* statement, const char* k return ADBC_STATUS_NOT_IMPLEMENTED; } +AdbcStatusCode StatementGetOptionBytes(struct AdbcStatement* statement, const char* key, + uint8_t* value, size_t* length, + struct AdbcError* error) { + return ADBC_STATUS_NOT_IMPLEMENTED; +} + AdbcStatusCode StatementGetOptionInt(struct AdbcStatement* statement, const char* key, int64_t* value, struct AdbcError* error) { return ADBC_STATUS_NOT_IMPLEMENTED; @@ -289,6 +318,11 @@ AdbcStatusCode StatementSetOption(struct AdbcStatement*, const char*, const char return ADBC_STATUS_NOT_IMPLEMENTED; } +AdbcStatusCode StatementSetOptionBytes(struct AdbcStatement*, const char*, const uint8_t*, + size_t, struct AdbcError* error) { + return ADBC_STATUS_NOT_IMPLEMENTED; +} + AdbcStatusCode StatementSetOptionInt(struct AdbcStatement* statement, const char* key, int64_t value, struct AdbcError* error) { return ADBC_STATUS_NOT_IMPLEMENTED; @@ -312,6 +346,7 @@ AdbcStatusCode StatementSetSubstraitPlan(struct AdbcStatement*, const uint8_t*, /// Temporary state while the database is being configured. struct TempDatabase { std::unordered_map options; + std::unordered_map bytes_options; std::unordered_map int_options; std::unordered_map double_options; std::string driver; @@ -323,6 +358,7 @@ struct TempDatabase { /// Temporary state while the database is being configured. struct TempConnection { std::unordered_map options; + std::unordered_map bytes_options; std::unordered_map int_options; std::unordered_map double_options; }; @@ -366,6 +402,28 @@ AdbcStatusCode AdbcDatabaseGetOption(struct AdbcDatabase* database, const char* return ADBC_STATUS_OK; } +AdbcStatusCode AdbcDatabaseGetOptionBytes(struct AdbcDatabase* database, const char* key, + uint8_t* value, size_t* length, + struct AdbcError* error) { + if (database->private_driver) { + return database->private_driver->DatabaseGetOptionBytes(database, key, value, length, + error); + } + const auto* args = reinterpret_cast(database->private_data); + const auto it = args->bytes_options.find(key); + if (it == args->options.end()) { + return ADBC_STATUS_NOT_FOUND; + } + const std::string& result = it->second; + + if (*length <= result.size()) { + // Enough space + std::memcpy(value, result.c_str(), result.size()); + } + *length = result.size(); + return ADBC_STATUS_OK; +} + AdbcStatusCode AdbcDatabaseGetOptionInt(struct AdbcDatabase* database, const char* key, int64_t* value, struct AdbcError* error) { if (database->private_driver) { @@ -411,6 +469,19 @@ AdbcStatusCode AdbcDatabaseSetOption(struct AdbcDatabase* database, const char* return ADBC_STATUS_OK; } +AdbcStatusCode AdbcDatabaseSetOptionBytes(struct AdbcDatabase* database, const char* key, + const uint8_t* value, size_t length, + struct AdbcError* error) { + if (database->private_driver) { + return database->private_driver->DatabaseSetOptionBytes(database, key, value, length, + error); + } + + TempDatabase* args = reinterpret_cast(database->private_data); + args->bytes_options[key] = std::string(reinterpret_cast(value), length); + return ADBC_STATUS_OK; +} + AdbcStatusCode AdbcDatabaseSetOptionInt(struct AdbcDatabase* database, const char* key, int64_t value, struct AdbcError* error) { if (database->private_driver) { @@ -490,6 +561,7 @@ AdbcStatusCode AdbcDatabaseInit(struct AdbcDatabase* database, struct AdbcError* return status; } auto options = std::move(args->options); + auto bytes_options = std::move(args->bytes_options); auto int_options = std::move(args->int_options); auto double_options = std::move(args->double_options); delete args; @@ -499,6 +571,13 @@ AdbcStatusCode AdbcDatabaseInit(struct AdbcDatabase* database, struct AdbcError* option.second.c_str(), error); if (status != ADBC_STATUS_OK) break; } + for (const auto& option : bytes_options) { + status = database->private_driver->DatabaseSetOptionBytes( + database, option.first.c_str(), + reinterpret_cast(option.second.data()), option.second.size(), + error); + if (status != ADBC_STATUS_OK) break; + } for (const auto& option : int_options) { status = database->private_driver->DatabaseSetOptionInt( database, option.first.c_str(), option.second, error); @@ -612,6 +691,30 @@ AdbcStatusCode AdbcConnectionGetOption(struct AdbcConnection* connection, const error); } +AdbcStatusCode AdbcConnectionGetOptionBytes(struct AdbcConnection* connection, + const char* key, uint8_t* value, + size_t* length, struct AdbcError* error) { + if (!connection->private_data) { + SetError(error, "AdbcConnectionGetOption: must AdbcConnectionNew first"); + return ADBC_STATUS_INVALID_STATE; + } + if (!connection->private_driver) { + // Init not yet called, get the saved option + const auto* args = reinterpret_cast(connection->private_data); + const auto it = args->bytes_options.find(key); + if (it == args->options.end()) { + return ADBC_STATUS_NOT_FOUND; + } + if (*length >= it->second.size() + 1) { + std::memcpy(value, it->second.data(), it->second.size() + 1); + } + *length = it->second.size() + 1; + return ADBC_STATUS_OK; + } + return connection->private_driver->ConnectionGetOptionBytes(connection, key, value, + length, error); +} + AdbcStatusCode AdbcConnectionGetOptionInt(struct AdbcConnection* connection, const char* key, int64_t* value, struct AdbcError* error) { @@ -688,6 +791,8 @@ AdbcStatusCode AdbcConnectionInit(struct AdbcConnection* connection, TempConnection* args = reinterpret_cast(connection->private_data); connection->private_data = nullptr; std::unordered_map options = std::move(args->options); + std::unordered_map bytes_options = + std::move(args->bytes_options); std::unordered_map int_options = std::move(args->int_options); std::unordered_map double_options = std::move(args->double_options); @@ -702,6 +807,13 @@ AdbcStatusCode AdbcConnectionInit(struct AdbcConnection* connection, connection, option.first.c_str(), option.second.c_str(), error); if (status != ADBC_STATUS_OK) return status; } + for (const auto& option : bytes_options) { + status = database->private_driver->ConnectionSetOptionBytes( + connection, option.first.c_str(), + reinterpret_cast(option.second.data()), option.second.size(), + error); + if (status != ADBC_STATUS_OK) return status; + } for (const auto& option : int_options) { status = database->private_driver->ConnectionSetOptionInt( connection, option.first.c_str(), option.second, error); @@ -776,6 +888,23 @@ AdbcStatusCode AdbcConnectionSetOption(struct AdbcConnection* connection, const return connection->private_driver->ConnectionSetOption(connection, key, value, error); } +AdbcStatusCode AdbcConnectionSetOptionBytes(struct AdbcConnection* connection, + const char* key, const uint8_t* value, + size_t length, struct AdbcError* error) { + if (!connection->private_data) { + SetError(error, "AdbcConnectionSetOptionInt: must AdbcConnectionNew first"); + return ADBC_STATUS_INVALID_STATE; + } + if (!connection->private_driver) { + // Init not yet called, save the option + TempConnection* args = reinterpret_cast(connection->private_data); + args->bytes_options[key] = std::string(reinterpret_cast(value), length); + return ADBC_STATUS_OK; + } + return connection->private_driver->ConnectionSetOptionBytes(connection, key, value, + length, error); +} + AdbcStatusCode AdbcConnectionSetOptionInt(struct AdbcConnection* connection, const char* key, int64_t value, struct AdbcError* error) { @@ -879,6 +1008,16 @@ AdbcStatusCode AdbcStatementGetOption(struct AdbcStatement* statement, const cha error); } +AdbcStatusCode AdbcStatementGetOptionBytes(struct AdbcStatement* statement, + const char* key, uint8_t* value, + size_t* length, struct AdbcError* error) { + if (!statement->private_driver) { + return ADBC_STATUS_INVALID_STATE; + } + return statement->private_driver->StatementGetOptionBytes(statement, key, value, length, + error); +} + AdbcStatusCode AdbcStatementGetOptionInt(struct AdbcStatement* statement, const char* key, int64_t* value, struct AdbcError* error) { if (!statement->private_driver) { @@ -943,6 +1082,16 @@ AdbcStatusCode AdbcStatementSetOption(struct AdbcStatement* statement, const cha return statement->private_driver->StatementSetOption(statement, key, value, error); } +AdbcStatusCode AdbcStatementSetOptionBytes(struct AdbcStatement* statement, + const char* key, const uint8_t* value, + size_t length, struct AdbcError* error) { + if (!statement->private_driver) { + return ADBC_STATUS_INVALID_STATE; + } + return statement->private_driver->StatementSetOptionBytes(statement, key, value, length, + error); +} + AdbcStatusCode AdbcStatementSetOptionInt(struct AdbcStatement* statement, const char* key, int64_t value, struct AdbcError* error) { if (!statement->private_driver) { @@ -1229,23 +1378,29 @@ AdbcStatusCode AdbcLoadDriverFromInitFunc(AdbcDriverInitFunc init_func, int vers if (version >= ADBC_VERSION_1_1_0) { auto* driver = reinterpret_cast(raw_driver); FILL_DEFAULT(driver, DatabaseGetOption); + FILL_DEFAULT(driver, DatabaseGetOptionBytes); FILL_DEFAULT(driver, DatabaseGetOptionInt); FILL_DEFAULT(driver, DatabaseGetOptionDouble); + FILL_DEFAULT(driver, DatabaseSetOptionBytes); FILL_DEFAULT(driver, DatabaseSetOptionInt); FILL_DEFAULT(driver, DatabaseSetOptionDouble); FILL_DEFAULT(driver, ConnectionCancel); FILL_DEFAULT(driver, ConnectionGetOption); + FILL_DEFAULT(driver, ConnectionGetOptionBytes); FILL_DEFAULT(driver, ConnectionGetOptionInt); FILL_DEFAULT(driver, ConnectionGetOptionDouble); + FILL_DEFAULT(driver, ConnectionSetOptionBytes); FILL_DEFAULT(driver, ConnectionSetOptionInt); FILL_DEFAULT(driver, ConnectionSetOptionDouble); FILL_DEFAULT(driver, StatementCancel); FILL_DEFAULT(driver, StatementExecuteSchema); FILL_DEFAULT(driver, StatementGetOption); + FILL_DEFAULT(driver, StatementGetOptionBytes); FILL_DEFAULT(driver, StatementGetOptionInt); FILL_DEFAULT(driver, StatementGetOptionDouble); + FILL_DEFAULT(driver, StatementSetOptionBytes); FILL_DEFAULT(driver, StatementSetOptionInt); FILL_DEFAULT(driver, StatementSetOptionDouble); }