diff --git a/bindings/c/fdb_c.cpp b/bindings/c/fdb_c.cpp index b34687901f..bc0a84a479 100644 --- a/bindings/c/fdb_c.cpp +++ b/bindings/c/fdb_c.cpp @@ -413,6 +413,33 @@ extern "C" DLLEXPORT void fdb_database_destroy(FDBDatabase* d) { CATCH_AND_DIE(DB(d)->delref();); } +// Define these symbols so that older client bindings (in particular, +// python) can load them at startup. Nobody should be calling this +// stuff in 8.0.0+ because it has always been experimental and is now +// deleted. +extern "C" DLLEXPORT fdb_error_t fdb_database_open_tenant(FDBDatabase* d, + uint8_t const* tenant_name, + int tenant_name_length, + FDBTenant** out_tenant) { + fprintf(stderr, "Unexpected call to removed functionality [fdb_database_open_tenant]\n"); + abort(); +} + +extern "C" DLLEXPORT fdb_error_t fdb_tenant_create_transaction(FDBTenant* tenant, FDBTransaction** out_transaction) { + fprintf(stderr, "Unexpected call to removed functionality [fdb_tenant_create_transaction]\n"); + abort(); +} + +extern "C" DLLEXPORT WARN_UNUSED_RESULT FDBFuture* fdb_tenant_get_id(FDBTenant* tenant) { + fprintf(stderr, "Unexpected call to removed functionality [fdb_tenant_get_id]\n"); + abort(); +} + +extern "C" DLLEXPORT void fdb_tenant_destroy(FDBTenant* tenant) { + fprintf(stderr, "Unexpected call to removed functionality [fdb_tenant_destroy]\n"); + abort(); +} + extern "C" DLLEXPORT fdb_error_t fdb_database_create_transaction(FDBDatabase* d, FDBTransaction** out_transaction) { CATCH_AND_RETURN(Reference tr = DB(d)->createTransaction(); if (g_api_version <= 15) tr->setOption(FDBTransactionOptions::ACCESS_SYSTEM_KEYS); diff --git a/bindings/c/foundationdb/fdb_c.h b/bindings/c/foundationdb/fdb_c.h index 5d484ab64c..e1951f6a88 100644 --- a/bindings/c/foundationdb/fdb_c.h +++ b/bindings/c/foundationdb/fdb_c.h @@ -376,6 +376,25 @@ DLLEXPORT WARN_UNUSED_RESULT fdb_error_t fdb_database_set_option(FDBDatabase* d, DLLEXPORT WARN_UNUSED_RESULT fdb_error_t fdb_database_create_transaction(FDBDatabase* d, FDBTransaction** out_transaction); +/* + * Dummy versions of tenant-related functions are needed in the FDB C library + * because 7.x python bindings always load these functions on startup. + * (In 8.0+, users should not be invoking this deleted experimental + * functionality directly.) + */ +typedef struct FDB_tenant FDBTenant; +DLLEXPORT WARN_UNUSED_RESULT fdb_error_t fdb_database_open_tenant(FDBDatabase* d, + uint8_t const* tenant_name, + int tenant_name_length, + FDBTenant** out_tenant); + +DLLEXPORT WARN_UNUSED_RESULT fdb_error_t fdb_tenant_create_transaction(FDBTenant* tenant, + FDBTransaction** out_transaction); + +DLLEXPORT WARN_UNUSED_RESULT FDBFuture* fdb_tenant_get_id(FDBTenant* tenant); + +DLLEXPORT void fdb_tenant_destroy(FDBTenant* tenant); + DLLEXPORT WARN_UNUSED_RESULT FDBFuture* fdb_database_reboot_worker(FDBDatabase* db, uint8_t const* address, int address_length, diff --git a/bindings/python/fdb/impl.py b/bindings/python/fdb/impl.py index 3d18fec008..7341dc8b2e 100644 --- a/bindings/python/fdb/impl.py +++ b/bindings/python/fdb/impl.py @@ -1302,6 +1302,25 @@ class Database(_TransactionCreator): def _set_option(self, option, param, length): self.capi.fdb_database_set_option(self.dpointer, option, param, length) + # XXX Adding this back temporarily to test C bindings changes to ensure + # that 7.x tenant-having python libraries can pass startup with 8.0.0 + # libfdb_c.so. Client code that actually calls tenant related APIs will + # of course not obtain useful functionality. Returning `None` here seems + # both necessary and sufficient to ensure that clients don't think that + # they are able to obtain tenant-related functionality. + # + # TODO(gglass): remove once we think the C library has been fixed + # up. We don't want to ship this stuff in 8.0.0 python bindings + # as that would perpetuate these unwanted dependencies on the C + # library. + def open_tenant(self, name): + tname = name # this is a bug + pointer = ctypes.c_void_p() + self.capi.fdb_database_open_tenant( + self.dpointer, tname, len(tname), ctypes.byref(pointer) + ) + return None + def create_transaction(self): pointer = ctypes.c_void_p() self.capi.fdb_database_create_transaction(self.dpointer, ctypes.byref(pointer)) @@ -1653,6 +1672,27 @@ def init_c_api(): _capi.fdb_database_destroy.argtypes = [ctypes.c_void_p] _capi.fdb_database_destroy.restype = None + # XXX Adding this back temporarily to test C bindings changes to put + # this stuff back in, to avoid breaking 7.x tenant-having python libraries + # that want to load these symbols on process startup. + # + # TODO(gglass): remove once we think the C library has been fixed + # up. We don't want to ship this stuff in 8.0.0 python bindings + # as that would perpetuate these unwanted dependencies on the C + # library. Alternatively, only initialize this stuff in a non-default + # mode to be used only by internal testing with the very specific + # goal of ensuring that the C library has symbols to satisfy + # 7.x python client libraries. Like "SIMULATE_7X_PYTHON_BINDINGS" + # mode. + _capi.fdb_database_open_tenant.argtypes = [ + ctypes.c_void_p, + ctypes.c_void_p, + ctypes.c_int, + ctypes.POINTER(ctypes.c_void_p), + ] + _capi.fdb_database_open_tenant.restype = ctypes.c_int + _capi.fdb_database_open_tenant.errcheck = check_error_code + _capi.fdb_database_create_transaction.argtypes = [ ctypes.c_void_p, ctypes.POINTER(ctypes.c_void_p), @@ -1672,6 +1712,19 @@ def init_c_api(): _capi.fdb_database_get_client_status.argtypes = [ctypes.c_void_p] _capi.fdb_database_get_client_status.restype = ctypes.c_void_p + _capi.fdb_tenant_destroy.argtypes = [ctypes.c_void_p] + _capi.fdb_tenant_destroy.restype = None + + _capi.fdb_tenant_get_id.argtypes = [ctypes.c_void_p] + _capi.fdb_tenant_get_id.restype = ctypes.c_void_p + + _capi.fdb_tenant_create_transaction.argtypes = [ + ctypes.c_void_p, + ctypes.POINTER(ctypes.c_void_p), + ] + _capi.fdb_tenant_create_transaction.restype = ctypes.c_int + _capi.fdb_tenant_create_transaction.errcheck = check_error_code + _capi.fdb_transaction_destroy.argtypes = [ctypes.c_void_p] _capi.fdb_transaction_destroy.restype = None