Merge pull request #942 from ajbeamon/remove-cluster-from-bindings
Remove cluster from bindings
This commit is contained in:
commit
04b94e74c7
|
@ -16,7 +16,9 @@ packaging/msi/FDBInstaller.msi
|
|||
*.pom
|
||||
bindings/java/pom*.xml
|
||||
bindings/java/src*/main/overview.html
|
||||
bindings/java/src*/main/com/apple/foundationdb/*Options.java
|
||||
bindings/java/src*/main/com/apple/foundationdb/NetworkOptions.java
|
||||
bindings/java/src*/main/com/apple/foundationdb/DatabaseOptions.java
|
||||
bindings/java/src*/main/com/apple/foundationdb/TransactionOptions.java
|
||||
bindings/java/src*/main/com/apple/foundationdb/StreamingMode.java
|
||||
bindings/java/src*/main/com/apple/foundationdb/MutationType.java
|
||||
bindings/java/src*/main/com/apple/foundationdb/ConflictRangeType.java
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
*/
|
||||
|
||||
#define FDB_API_VERSION 610
|
||||
#define FDB_INCLUDE_LEGACY_TYPES
|
||||
|
||||
#include "fdbclient/MultiVersionTransaction.h"
|
||||
#include "foundationdb/fdb_c.h"
|
||||
|
@ -31,17 +32,18 @@ int g_api_version = 0;
|
|||
*
|
||||
* type mapping:
|
||||
* FDBFuture -> ThreadSingleAssignmentVarBase
|
||||
* FDBCluster -> char
|
||||
* FDBDatabase -> IDatabase
|
||||
* FDBTransaction -> ITransaction
|
||||
*/
|
||||
#define TSAVB(f) ((ThreadSingleAssignmentVarBase*)(f))
|
||||
#define TSAV(T, f) ((ThreadSingleAssignmentVar<T>*)(f))
|
||||
|
||||
#define CLUSTER(c) ((char*)c)
|
||||
#define DB(d) ((IDatabase*)d)
|
||||
#define TXN(t) ((ITransaction*)t)
|
||||
|
||||
// Legacy (pre API version 610)
|
||||
#define CLUSTER(c) ((char*)c)
|
||||
|
||||
/*
|
||||
* While we could just use the MultiVersionApi instance directly, this #define allows us to swap in any other IClientApi instance (e.g. from ThreadSafeApi)
|
||||
*/
|
||||
|
@ -132,16 +134,6 @@ fdb_error_t fdb_add_network_thread_completion_hook(void (*hook)(void*), void *ho
|
|||
CATCH_AND_RETURN( API->addNetworkThreadCompletionHook(hook, hook_parameter); );
|
||||
}
|
||||
|
||||
|
||||
extern "C" DLLEXPORT
|
||||
FDBFuture* fdb_cluster_configure_database( FDBCluster* c, int config_type,
|
||||
int config_mode, uint8_t const* db_name,
|
||||
int db_name_length )
|
||||
{
|
||||
// Obsolete, but needed for linker compatibility with api version 12 and below
|
||||
return (FDBFuture*)ThreadFuture<Void>(client_invalid_operation()).extractPtr();
|
||||
}
|
||||
|
||||
extern "C" DLLEXPORT
|
||||
void fdb_future_cancel( FDBFuture* f ) {
|
||||
CATCH_AND_DIE(
|
||||
|
@ -235,14 +227,14 @@ fdb_error_t fdb_future_get_key( FDBFuture* f, uint8_t const** out_key,
|
|||
}
|
||||
|
||||
extern "C" DLLEXPORT
|
||||
fdb_error_t fdb_future_get_cluster( FDBFuture* f, FDBCluster** out_cluster ) {
|
||||
fdb_error_t fdb_future_get_cluster_v609( FDBFuture* f, FDBCluster** out_cluster ) {
|
||||
CATCH_AND_RETURN(
|
||||
*out_cluster = (FDBCluster*)
|
||||
( (TSAV( char*, f )->get() ) ); );
|
||||
}
|
||||
|
||||
extern "C" DLLEXPORT
|
||||
fdb_error_t fdb_future_get_database( FDBFuture* f, FDBDatabase** out_database ) {
|
||||
fdb_error_t fdb_future_get_database_v609( FDBFuture* f, FDBDatabase** out_database ) {
|
||||
CATCH_AND_RETURN(
|
||||
*out_database = (FDBDatabase*)
|
||||
( (TSAV( Reference<IDatabase>, f )->get() ).extractPtr() ); );
|
||||
|
@ -294,7 +286,7 @@ fdb_error_t fdb_future_get_string_array(
|
|||
}
|
||||
|
||||
extern "C" DLLEXPORT
|
||||
FDBFuture* fdb_create_cluster( const char* cluster_file_path ) {
|
||||
FDBFuture* fdb_create_cluster_v609( const char* cluster_file_path ) {
|
||||
char *path;
|
||||
if(cluster_file_path) {
|
||||
path = new char[strlen(cluster_file_path) + 1];
|
||||
|
@ -308,7 +300,7 @@ FDBFuture* fdb_create_cluster( const char* cluster_file_path ) {
|
|||
}
|
||||
|
||||
extern "C" DLLEXPORT
|
||||
fdb_error_t fdb_cluster_set_option( FDBCluster* c,
|
||||
fdb_error_t fdb_cluster_set_option_v609( FDBCluster* c,
|
||||
FDBClusterOption option,
|
||||
uint8_t const* value,
|
||||
int value_length )
|
||||
|
@ -318,19 +310,32 @@ fdb_error_t fdb_cluster_set_option( FDBCluster* c,
|
|||
}
|
||||
|
||||
extern "C" DLLEXPORT
|
||||
void fdb_cluster_destroy( FDBCluster* c ) {
|
||||
void fdb_cluster_destroy_v609( FDBCluster* c ) {
|
||||
CATCH_AND_DIE( delete[] CLUSTER(c); );
|
||||
}
|
||||
|
||||
extern "C" DLLEXPORT
|
||||
FDBFuture* fdb_cluster_create_database( FDBCluster* c, uint8_t const* db_name,
|
||||
FDBFuture* fdb_cluster_create_database_v609( FDBCluster* c, uint8_t const* db_name,
|
||||
int db_name_length )
|
||||
{
|
||||
if(strncmp((const char*)db_name, "DB", db_name_length) != 0) {
|
||||
return (FDBFuture*)ThreadFuture<Reference<IDatabase>>(invalid_database_name()).extractPtr();
|
||||
}
|
||||
|
||||
return (FDBFuture*) API->createDatabase(CLUSTER(c)).extractPtr();
|
||||
FDBDatabase *db;
|
||||
fdb_error_t err = fdb_create_database(CLUSTER(c), &db);
|
||||
if(err) {
|
||||
return (FDBFuture*)ThreadFuture<Reference<IDatabase>>(Error(err)).extractPtr();
|
||||
}
|
||||
|
||||
return (FDBFuture*)ThreadFuture<Reference<IDatabase>>(Reference<IDatabase>(DB(db))).extractPtr();
|
||||
}
|
||||
|
||||
extern "C" DLLEXPORT
|
||||
fdb_error_t fdb_create_database( const char* cluster_file_path, FDBDatabase** out_database ) {
|
||||
CATCH_AND_RETURN(
|
||||
*out_database = (FDBDatabase*)API->createDatabase( cluster_file_path ? cluster_file_path : "" ).extractPtr();
|
||||
);
|
||||
}
|
||||
|
||||
extern "C" DLLEXPORT
|
||||
|
@ -663,6 +668,12 @@ fdb_error_t fdb_select_api_version_impl( int runtime_version, int header_version
|
|||
// Versioned API changes -- descending order by version (new changes at top)
|
||||
// FDB_API_CHANGED( function, ver ) means there is a new implementation as of ver, and a function function_(ver-1) is the old implementation
|
||||
// FDB_API_REMOVED( function, ver ) means the function was removed as of ver, and function_(ver-1) is the old implementation
|
||||
FDB_API_REMOVED( fdb_create_cluster, 610 );
|
||||
FDB_API_REMOVED( fdb_cluster_create_database, 610 );
|
||||
FDB_API_REMOVED( fdb_cluster_set_option, 610 );
|
||||
FDB_API_REMOVED( fdb_cluster_destroy, 610 );
|
||||
FDB_API_REMOVED( fdb_future_get_cluster, 610 );
|
||||
FDB_API_REMOVED( fdb_future_get_database, 610 );
|
||||
FDB_API_CHANGED( fdb_future_get_error, 23 );
|
||||
FDB_API_REMOVED( fdb_future_is_error, 23 );
|
||||
FDB_API_CHANGED( fdb_future_get_keyvalue_array, 14 );
|
||||
|
|
|
@ -62,7 +62,6 @@ extern "C" {
|
|||
|
||||
/* Pointers to these opaque types represent objects in the FDB API */
|
||||
typedef struct FDB_future FDBFuture;
|
||||
typedef struct FDB_cluster FDBCluster;
|
||||
typedef struct FDB_database FDBDatabase;
|
||||
typedef struct FDB_transaction FDBTransaction;
|
||||
|
||||
|
@ -128,12 +127,6 @@ extern "C" {
|
|||
fdb_future_get_key( FDBFuture* f, uint8_t const** out_key,
|
||||
int* out_key_length );
|
||||
|
||||
DLLEXPORT WARN_UNUSED_RESULT fdb_error_t
|
||||
fdb_future_get_cluster( FDBFuture* f, FDBCluster** out_cluster );
|
||||
|
||||
DLLEXPORT WARN_UNUSED_RESULT fdb_error_t
|
||||
fdb_future_get_database( FDBFuture* f, FDBDatabase** out_database );
|
||||
|
||||
DLLEXPORT WARN_UNUSED_RESULT fdb_error_t
|
||||
fdb_future_get_value( FDBFuture* f, fdb_bool_t *out_present,
|
||||
uint8_t const** out_value,
|
||||
|
@ -148,17 +141,8 @@ extern "C" {
|
|||
DLLEXPORT WARN_UNUSED_RESULT fdb_error_t fdb_future_get_string_array(FDBFuture* f,
|
||||
const char*** out_strings, int* out_count);
|
||||
|
||||
DLLEXPORT WARN_UNUSED_RESULT FDBFuture* fdb_create_cluster( const char* cluster_file_path );
|
||||
|
||||
DLLEXPORT void fdb_cluster_destroy( FDBCluster* c );
|
||||
|
||||
DLLEXPORT WARN_UNUSED_RESULT fdb_error_t
|
||||
fdb_cluster_set_option( FDBCluster* c, FDBClusterOption option,
|
||||
uint8_t const* value, int value_length );
|
||||
|
||||
DLLEXPORT WARN_UNUSED_RESULT FDBFuture*
|
||||
fdb_cluster_create_database( FDBCluster* c, uint8_t const* db_name,
|
||||
int db_name_length );
|
||||
fdb_create_database( const char* cluster_file_path, FDBDatabase** out_database );
|
||||
|
||||
DLLEXPORT void fdb_database_destroy( FDBDatabase* d );
|
||||
|
||||
|
@ -269,6 +253,35 @@ extern "C" {
|
|||
|
||||
/* LEGACY API VERSIONS */
|
||||
|
||||
#if FDB_API_VERSION < 610 || defined FDB_INCLUDE_LEGACY_TYPES
|
||||
typedef struct FDB_cluster FDBCluster;
|
||||
|
||||
typedef enum {
|
||||
// This option is only a placeholder for C compatibility and should not be used
|
||||
FDB_CLUSTER_OPTION_DUMMY_DO_NOT_USE=-1
|
||||
} FDBClusterOption;
|
||||
#endif
|
||||
|
||||
#if FDB_API_VERSION < 610
|
||||
DLLEXPORT WARN_UNUSED_RESULT fdb_error_t
|
||||
fdb_future_get_cluster( FDBFuture* f, FDBCluster** out_cluster );
|
||||
|
||||
DLLEXPORT WARN_UNUSED_RESULT fdb_error_t
|
||||
fdb_future_get_database( FDBFuture* f, FDBDatabase** out_database );
|
||||
|
||||
DLLEXPORT WARN_UNUSED_RESULT FDBFuture* fdb_create_cluster( const char* cluster_file_path );
|
||||
|
||||
DLLEXPORT void fdb_cluster_destroy( FDBCluster* c );
|
||||
|
||||
DLLEXPORT WARN_UNUSED_RESULT fdb_error_t
|
||||
fdb_cluster_set_option( FDBCluster* c, FDBClusterOption option,
|
||||
uint8_t const* value, int value_length );
|
||||
|
||||
DLLEXPORT WARN_UNUSED_RESULT FDBFuture*
|
||||
fdb_cluster_create_database( FDBCluster* c, uint8_t const* db_name,
|
||||
int db_name_length );
|
||||
#endif
|
||||
|
||||
#if FDB_API_VERSION < 23
|
||||
DLLEXPORT WARN_UNUSED_RESULT fdb_error_t
|
||||
fdb_future_get_error( FDBFuture* f,
|
||||
|
|
|
@ -236,22 +236,8 @@ FDBDatabase* openDatabase(struct ResultSet *rs, pthread_t *netThread) {
|
|||
checkError(fdb_setup_network(), "setup network", rs);
|
||||
pthread_create(netThread, NULL, &runNetwork, NULL);
|
||||
|
||||
FDBFuture *f = fdb_create_cluster(NULL);
|
||||
checkError(fdb_future_block_until_ready(f), "block for cluster", rs);
|
||||
|
||||
FDBCluster *cluster;
|
||||
checkError(fdb_future_get_cluster(f, &cluster), "get cluster", rs);
|
||||
|
||||
fdb_future_destroy(f);
|
||||
|
||||
f = fdb_cluster_create_database(cluster, (uint8_t*)"DB", 2);
|
||||
checkError(fdb_future_block_until_ready(f), "block for database", rs);
|
||||
|
||||
FDBDatabase *db;
|
||||
checkError(fdb_future_get_database(f, &db), "get database", rs);
|
||||
|
||||
fdb_future_destroy(f);
|
||||
fdb_cluster_destroy(cluster);
|
||||
checkError(fdb_create_database(NULL, &db), "create database", rs);
|
||||
|
||||
return db;
|
||||
}
|
||||
|
|
|
@ -34,8 +34,7 @@ THREAD_FUNC networkThread(void* fdb) {
|
|||
|
||||
ACTOR Future<Void> _test() {
|
||||
API *fdb = FDB::API::selectAPIVersion(610);
|
||||
auto c = fdb->createCluster( std::string() );
|
||||
auto db = c->createDatabase();
|
||||
auto db = fdb->createDatabase();
|
||||
state Reference<Transaction> tr( new Transaction(db) );
|
||||
|
||||
// tr->setVersion(1);
|
||||
|
@ -189,13 +188,13 @@ namespace FDB {
|
|||
}
|
||||
|
||||
Reference<Cluster> API::createCluster( std::string const& connFilename ) {
|
||||
CFuture f( fdb_create_cluster( connFilename.c_str() ) );
|
||||
f.blockUntilReady();
|
||||
return Reference<Cluster>(new Cluster(connFilename));
|
||||
}
|
||||
|
||||
FDBCluster* c;
|
||||
throw_on_error( fdb_future_get_cluster( f.f, &c ) );
|
||||
|
||||
return Reference<Cluster>( new Cluster(c) );
|
||||
Reference<DatabaseContext> API::createDatabase(std::string const& connFilename) {
|
||||
FDBDatabase *db;
|
||||
throw_on_error(fdb_create_database(connFilename.c_str(), &db));
|
||||
return Reference<DatabaseContext>(new DatabaseContext(db));
|
||||
}
|
||||
|
||||
int API::getAPIVersion() const {
|
||||
|
@ -203,14 +202,7 @@ namespace FDB {
|
|||
}
|
||||
|
||||
Reference<DatabaseContext> Cluster::createDatabase() {
|
||||
const char *dbName = "DB";
|
||||
CFuture f( fdb_cluster_create_database( c, (uint8_t*)dbName, (int)strlen(dbName) ) );
|
||||
f.blockUntilReady();
|
||||
|
||||
FDBDatabase* db;
|
||||
throw_on_error( fdb_future_get_database( f.f, &db ) );
|
||||
|
||||
return Reference<DatabaseContext>( new DatabaseContext(db) );
|
||||
return API::getInstance()->createDatabase(connFilename.c_str());
|
||||
}
|
||||
|
||||
void DatabaseContext::setDatabaseOption(FDBDatabaseOption option, Optional<StringRef> value) {
|
||||
|
|
|
@ -44,20 +44,21 @@ namespace FDB {
|
|||
private:
|
||||
FDBDatabase* db;
|
||||
explicit DatabaseContext( FDBDatabase* db ) : db(db) {}
|
||||
|
||||
friend class API;
|
||||
};
|
||||
|
||||
// Deprecated: Use createDatabase instead.
|
||||
class Cluster : public ReferenceCounted<Cluster>, NonCopyable {
|
||||
public:
|
||||
~Cluster() {
|
||||
fdb_cluster_destroy( c );
|
||||
}
|
||||
~Cluster() {}
|
||||
|
||||
Reference<DatabaseContext> createDatabase();
|
||||
|
||||
private:
|
||||
explicit Cluster( FDBCluster* c ) : c(c) {}
|
||||
FDBCluster* c;
|
||||
explicit Cluster( std::string connFilename ) : connFilename(connFilename) {}
|
||||
|
||||
std::string connFilename;
|
||||
friend class API;
|
||||
};
|
||||
|
||||
|
@ -73,8 +74,11 @@ namespace FDB {
|
|||
void runNetwork();
|
||||
void stopNetwork();
|
||||
|
||||
// Deprecated: Use createDatabase instead.
|
||||
Reference<Cluster> createCluster( std::string const& connFilename );
|
||||
|
||||
Reference<DatabaseContext> createDatabase( std::string const& connFilename="" );
|
||||
|
||||
bool evaluatePredicate(FDBErrorPredicate pred, Error const& e);
|
||||
int getAPIVersion() const;
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#include <string.h>
|
||||
#endif
|
||||
|
||||
// Otherwise we have to type setupNetwork(), Cluster::createCluster(), etc.
|
||||
// Otherwise we have to type setupNetwork(), FDB::open(), etc.
|
||||
using namespace FDB;
|
||||
|
||||
std::map<std::string, FDBMutationType> optionInfo;
|
||||
|
@ -1714,8 +1714,7 @@ ACTOR void startTest(std::string clusterFilename, StringRef prefix, int apiVersi
|
|||
startThread(networkThread, fdb);
|
||||
|
||||
// Connect to the default cluster/database, and create a transaction
|
||||
auto cluster = fdb->createCluster(clusterFilename);
|
||||
Reference<DatabaseContext> db = cluster->createDatabase();
|
||||
auto db = fdb->createDatabase(clusterFilename);
|
||||
|
||||
Reference<FlowTesterData> data = Reference<FlowTesterData>(new FlowTesterData(fdb));
|
||||
wait(runTest(data, db, prefix));
|
||||
|
@ -1744,8 +1743,7 @@ ACTOR void _test_versionstamp() {
|
|||
fdb->setupNetwork();
|
||||
startThread(networkThread, fdb);
|
||||
|
||||
auto c = fdb->createCluster(std::string());
|
||||
auto db = c->createDatabase();
|
||||
auto db = fdb->createDatabase();
|
||||
state Reference<Transaction> tr(new Transaction(db));
|
||||
|
||||
state Future<FDBStandalone<StringRef>> ftrVersion = tr->getVersionstamp();
|
||||
|
|
|
@ -893,7 +893,7 @@ func main() {
|
|||
log.Fatal("API version not equal to value selected")
|
||||
}
|
||||
|
||||
db, e = fdb.Open(clusterFile, []byte("DB"))
|
||||
db, e = fdb.OpenDatabase(clusterFile)
|
||||
if e != nil {
|
||||
log.Fatal(e)
|
||||
}
|
||||
|
|
|
@ -28,47 +28,18 @@ package fdb
|
|||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
)
|
||||
|
||||
// Deprecated: Use OpenDatabase or OpenDefault to obtain a database handle directly
|
||||
// Cluster is a handle to a FoundationDB cluster. Cluster is a lightweight
|
||||
// object that may be efficiently copied, and is safe for concurrent use by
|
||||
// multiple goroutines.
|
||||
//
|
||||
// It is generally preferable to use Open or OpenDefault to obtain a database
|
||||
// handle directly.
|
||||
type Cluster struct {
|
||||
*cluster
|
||||
clusterFileName string
|
||||
}
|
||||
|
||||
type cluster struct {
|
||||
ptr *C.FDBCluster
|
||||
}
|
||||
|
||||
func (c *cluster) destroy() {
|
||||
C.fdb_cluster_destroy(c.ptr)
|
||||
}
|
||||
|
||||
// OpenDatabase returns a database handle from the FoundationDB cluster. It is
|
||||
// generally preferable to use Open or OpenDefault to obtain a database handle
|
||||
// directly.
|
||||
// Deprecated: Use OpenDatabase or OpenDefault to obtain a database handle directly
|
||||
// OpenDatabase returns a database handle from the FoundationDB cluster.
|
||||
//
|
||||
// In the current release, the database name must be []byte("DB").
|
||||
// The database name must be []byte("DB").
|
||||
func (c Cluster) OpenDatabase(dbName []byte) (Database, error) {
|
||||
f := C.fdb_cluster_create_database(c.ptr, byteSliceToPtr(dbName), C.int(len(dbName)))
|
||||
fdb_future_block_until_ready(f)
|
||||
|
||||
var outd *C.FDBDatabase
|
||||
|
||||
if err := C.fdb_future_get_database(f, &outd); err != 0 {
|
||||
return Database{}, Error{int(err)}
|
||||
}
|
||||
|
||||
C.fdb_future_destroy(f)
|
||||
|
||||
d := &database{outd}
|
||||
runtime.SetFinalizer(d, (*database).destroy)
|
||||
|
||||
return Database{d}, nil
|
||||
return Open(c.clusterFileName, dbName)
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ package fdb
|
|||
import "C"
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"log"
|
||||
"runtime"
|
||||
|
@ -192,17 +193,10 @@ var apiVersion int
|
|||
var networkStarted bool
|
||||
var networkMutex sync.Mutex
|
||||
|
||||
type DatabaseId struct {
|
||||
clusterFile string
|
||||
dbName string
|
||||
}
|
||||
|
||||
var openClusters map[string]Cluster
|
||||
var openDatabases map[DatabaseId]Database
|
||||
var openDatabases map[string]Database
|
||||
|
||||
func init() {
|
||||
openClusters = make(map[string]Cluster)
|
||||
openDatabases = make(map[DatabaseId]Database)
|
||||
openDatabases = make(map[string]Database)
|
||||
}
|
||||
|
||||
func startNetwork() error {
|
||||
|
@ -222,10 +216,9 @@ func startNetwork() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// StartNetwork initializes the FoundationDB client networking engine. It is not
|
||||
// necessary to call StartNetwork when using the fdb.Open or fdb.OpenDefault
|
||||
// functions to obtain a database handle. StartNetwork must not be called more
|
||||
// than once.
|
||||
// Deprecated: the network is started automatically when a database is opened.
|
||||
// StartNetwork initializes the FoundationDB client networking engine. StartNetwork
|
||||
// must not be called more than once.
|
||||
func StartNetwork() error {
|
||||
networkMutex.Lock()
|
||||
defer networkMutex.Unlock()
|
||||
|
@ -237,17 +230,15 @@ func StartNetwork() error {
|
|||
return startNetwork()
|
||||
}
|
||||
|
||||
// DefaultClusterFile should be passed to fdb.Open or fdb.CreateCluster to allow
|
||||
// the FoundationDB C library to select the platform-appropriate default cluster
|
||||
// file on the current machine.
|
||||
// DefaultClusterFile should be passed to fdb.Open to allow the FoundationDB C
|
||||
// library to select the platform-appropriate default cluster file on the current machine.
|
||||
const DefaultClusterFile string = ""
|
||||
|
||||
// OpenDefault returns a database handle to the default database from the
|
||||
// FoundationDB cluster identified by the DefaultClusterFile on the current
|
||||
// machine. The FoundationDB client networking engine will be initialized first,
|
||||
// if necessary.
|
||||
// OpenDefault returns a database handle to the FoundationDB cluster identified
|
||||
// by the DefaultClusterFile on the current machine. The FoundationDB client
|
||||
// networking engine will be initialized first, if necessary.
|
||||
func OpenDefault() (Database, error) {
|
||||
return Open(DefaultClusterFile, []byte("DB"))
|
||||
return OpenDatabase(DefaultClusterFile)
|
||||
}
|
||||
|
||||
// MustOpenDefault is like OpenDefault but panics if the default database cannot
|
||||
|
@ -260,13 +251,9 @@ func MustOpenDefault() Database {
|
|||
return db
|
||||
}
|
||||
|
||||
// Open returns a database handle to the named database from the FoundationDB
|
||||
// cluster identified by the provided cluster file and database name. The
|
||||
// FoundationDB client networking engine will be initialized first, if
|
||||
// necessary.
|
||||
//
|
||||
// In the current release, the database name must be []byte("DB").
|
||||
func Open(clusterFile string, dbName []byte) (Database, error) {
|
||||
// Open returns a database handle to the FoundationDB cluster identified
|
||||
// by the provided cluster file and database name.
|
||||
func OpenDatabase(clusterFile string) (Database, error) {
|
||||
networkMutex.Lock()
|
||||
defer networkMutex.Unlock()
|
||||
|
||||
|
@ -283,27 +270,36 @@ func Open(clusterFile string, dbName []byte) (Database, error) {
|
|||
}
|
||||
}
|
||||
|
||||
cluster, ok := openClusters[clusterFile]
|
||||
db, ok := openDatabases[clusterFile]
|
||||
if !ok {
|
||||
cluster, e = createCluster(clusterFile)
|
||||
db, e = createDatabase(clusterFile)
|
||||
if e != nil {
|
||||
return Database{}, e
|
||||
}
|
||||
openClusters[clusterFile] = cluster
|
||||
}
|
||||
|
||||
db, ok := openDatabases[DatabaseId{clusterFile, string(dbName)}]
|
||||
if !ok {
|
||||
db, e = cluster.OpenDatabase(dbName)
|
||||
if e != nil {
|
||||
return Database{}, e
|
||||
}
|
||||
openDatabases[DatabaseId{clusterFile, string(dbName)}] = db
|
||||
openDatabases[clusterFile] = db
|
||||
}
|
||||
|
||||
return db, nil
|
||||
}
|
||||
|
||||
func MustOpenDatabase(clusterFile string) Database {
|
||||
db, err := OpenDatabase(clusterFile)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return db
|
||||
}
|
||||
|
||||
// Deprecated: Use OpenDatabase instead
|
||||
// The database name must be []byte("DB").
|
||||
func Open(clusterFile string, dbName []byte) (Database, error) {
|
||||
if bytes.Compare(dbName, []byte("DB")) != 0 {
|
||||
return Database{}, Error{2013} // invalid_database_name
|
||||
}
|
||||
return OpenDatabase(clusterFile)
|
||||
}
|
||||
|
||||
// Deprecated: Use MustOpenDatabase instead
|
||||
// MustOpen is like Open but panics if the database cannot be opened.
|
||||
func MustOpen(clusterFile string, dbName []byte) Database {
|
||||
db, err := Open(clusterFile, dbName)
|
||||
|
@ -313,7 +309,7 @@ func MustOpen(clusterFile string, dbName []byte) Database {
|
|||
return db
|
||||
}
|
||||
|
||||
func createCluster(clusterFile string) (Cluster, error) {
|
||||
func createDatabase(clusterFile string) (Database, error) {
|
||||
var cf *C.char
|
||||
|
||||
if len(clusterFile) != 0 {
|
||||
|
@ -321,23 +317,18 @@ func createCluster(clusterFile string) (Cluster, error) {
|
|||
defer C.free(unsafe.Pointer(cf))
|
||||
}
|
||||
|
||||
f := C.fdb_create_cluster(cf)
|
||||
fdb_future_block_until_ready(f)
|
||||
|
||||
var outc *C.FDBCluster
|
||||
|
||||
if err := C.fdb_future_get_cluster(f, &outc); err != 0 {
|
||||
return Cluster{}, Error{int(err)}
|
||||
var outdb *C.FDBDatabase
|
||||
if err := C.fdb_create_database(cf, &outdb); err != 0 {
|
||||
return Database{}, Error{int(err)}
|
||||
}
|
||||
|
||||
C.fdb_future_destroy(f)
|
||||
db := &database{outdb}
|
||||
runtime.SetFinalizer(db, (*database).destroy)
|
||||
|
||||
c := &cluster{outc}
|
||||
runtime.SetFinalizer(c, (*cluster).destroy)
|
||||
|
||||
return Cluster{c}, nil
|
||||
return Database{db}, nil
|
||||
}
|
||||
|
||||
// Deprecated: Use OpenDatabase instead.
|
||||
// CreateCluster returns a cluster handle to the FoundationDB cluster identified
|
||||
// by the provided cluster file.
|
||||
func CreateCluster(clusterFile string) (Cluster, error) {
|
||||
|
@ -352,7 +343,7 @@ func CreateCluster(clusterFile string) (Cluster, error) {
|
|||
return Cluster{}, errNetworkNotSetup
|
||||
}
|
||||
|
||||
return createCluster(clusterFile)
|
||||
return Cluster{clusterFile}, nil
|
||||
}
|
||||
|
||||
func byteSliceToPtr(b []byte) *C.uint8_t {
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
#include <foundationdb/fdb_c.h>
|
||||
|
||||
#define JNI_NULL 0
|
||||
#define JNI_NULL nullptr
|
||||
|
||||
#if defined(__GNUG__)
|
||||
#define thread_local __thread
|
||||
|
@ -38,15 +38,15 @@
|
|||
#error Missing thread local storage
|
||||
#endif
|
||||
|
||||
static JavaVM* g_jvm = 0;
|
||||
static thread_local JNIEnv* g_thread_jenv = 0; // Defined for the network thread once it is running, and for any thread that has called registerCallback
|
||||
static thread_local jmethodID g_IFutureCallback_call_methodID = 0;
|
||||
static JavaVM* g_jvm = nullptr;
|
||||
static thread_local JNIEnv* g_thread_jenv = nullptr; // Defined for the network thread once it is running, and for any thread that has called registerCallback
|
||||
static thread_local jmethodID g_IFutureCallback_call_methodID = JNI_NULL;
|
||||
static thread_local bool is_external = false;
|
||||
|
||||
void detachIfExternalThread(void *ignore) {
|
||||
if(is_external && g_thread_jenv != 0) {
|
||||
g_thread_jenv = 0;
|
||||
g_IFutureCallback_call_methodID = 0;
|
||||
if(is_external && g_thread_jenv != nullptr) {
|
||||
g_thread_jenv = nullptr;
|
||||
g_IFutureCallback_call_methodID = JNI_NULL;
|
||||
g_jvm->DetachCurrentThread();
|
||||
}
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ void throwOutOfMem(JNIEnv *jenv) {
|
|||
if(jenv->ExceptionOccurred())
|
||||
return;
|
||||
|
||||
if( jenv->ThrowNew( illegalArgClass, NULL ) != 0 ) {
|
||||
if( jenv->ThrowNew( illegalArgClass, nullptr ) != 0 ) {
|
||||
if( !jenv->ExceptionOccurred() ) {
|
||||
jenv->FatalError("Could not throw OutOfMemoryError");
|
||||
} else {
|
||||
|
@ -68,7 +68,7 @@ void throwOutOfMem(JNIEnv *jenv) {
|
|||
}
|
||||
}
|
||||
|
||||
static jthrowable getThrowable(JNIEnv *jenv, fdb_error_t e, const char* msg = NULL) {
|
||||
static jthrowable getThrowable(JNIEnv *jenv, fdb_error_t e, const char* msg = nullptr) {
|
||||
jclass excepClass = jenv->FindClass("com/apple/foundationdb/FDBException");
|
||||
if(jenv->ExceptionOccurred())
|
||||
return JNI_NULL;
|
||||
|
@ -128,11 +128,11 @@ static bool findCallbackMethods(JNIEnv *jenv) {
|
|||
}
|
||||
|
||||
static void callCallback( FDBFuture* f, void* data ) {
|
||||
if (g_thread_jenv == 0) {
|
||||
if (g_thread_jenv == nullptr) {
|
||||
// We are on an external thread and must attach to the JVM.
|
||||
// The shutdown hook will later detach this thread.
|
||||
is_external = true;
|
||||
if( g_jvm != 0 && g_jvm->AttachCurrentThreadAsDaemon((void **) &g_thread_jenv, JNI_NULL) == JNI_OK ) {
|
||||
if( g_jvm != nullptr && g_jvm->AttachCurrentThreadAsDaemon((void **) &g_thread_jenv, nullptr) == JNI_OK ) {
|
||||
if( !findCallbackMethods( g_thread_jenv ) ) {
|
||||
g_thread_jenv->FatalError("FDB: Could not find callback method.\n");
|
||||
}
|
||||
|
@ -169,9 +169,9 @@ JNIEXPORT void JNICALL Java_com_apple_foundationdb_NativeFuture_Future_1register
|
|||
}
|
||||
FDBFuture *f = (FDBFuture *)future;
|
||||
|
||||
// This is documented as not throwing, but simply returning NULL on OMM.
|
||||
// This is documented as not throwing, but simply returning null on OOM.
|
||||
// As belt and suspenders, we will check for pending exceptions and then,
|
||||
// if there are none and the result is NULL, we'll throw our own OMM.
|
||||
// if there are none and the result is null, we'll throw our own OOM.
|
||||
callback = jenv->NewGlobalRef( callback );
|
||||
if( !callback ) {
|
||||
if( !jenv->ExceptionOccurred() )
|
||||
|
@ -280,7 +280,7 @@ JNIEXPORT jobject JNICALL Java_com_apple_foundationdb_FutureStrings_FutureString
|
|||
jclass str_clazz = jenv->FindClass("java/lang/String");
|
||||
if( jenv->ExceptionOccurred() )
|
||||
return JNI_NULL;
|
||||
jobjectArray arr = jenv->NewObjectArray(count, str_clazz, NULL);
|
||||
jobjectArray arr = jenv->NewObjectArray(count, str_clazz, JNI_NULL);
|
||||
if( !arr ) {
|
||||
if( !jenv->ExceptionOccurred() )
|
||||
throwOutOfMem(jenv);
|
||||
|
@ -327,7 +327,7 @@ JNIEXPORT jobject JNICALL Java_com_apple_foundationdb_FutureResults_FutureResult
|
|||
return JNI_NULL;
|
||||
}
|
||||
|
||||
jbyteArray lastKey = NULL;
|
||||
jbyteArray lastKey = JNI_NULL;
|
||||
if(count) {
|
||||
lastKey = jenv->NewByteArray(kvs[count - 1].key_length);
|
||||
if( !lastKey ) {
|
||||
|
@ -378,7 +378,7 @@ JNIEXPORT jobject JNICALL Java_com_apple_foundationdb_FutureResults_FutureResult
|
|||
throwOutOfMem(jenv);
|
||||
return JNI_NULL;
|
||||
}
|
||||
uint8_t *keyvalues_barr = (uint8_t *)jenv->GetByteArrayElements(keyValueArray, NULL);
|
||||
uint8_t *keyvalues_barr = (uint8_t *)jenv->GetByteArrayElements(keyValueArray, JNI_NULL);
|
||||
if (!keyvalues_barr) {
|
||||
throwRuntimeEx( jenv, "Error getting handle to native resources" );
|
||||
return JNI_NULL;
|
||||
|
@ -393,7 +393,7 @@ JNIEXPORT jobject JNICALL Java_com_apple_foundationdb_FutureResults_FutureResult
|
|||
return JNI_NULL;
|
||||
}
|
||||
|
||||
jint *length_barr = jenv->GetIntArrayElements(lengthArray, NULL);
|
||||
jint *length_barr = jenv->GetIntArrayElements(lengthArray, JNI_NULL);
|
||||
if( !length_barr ) {
|
||||
if( !jenv->ExceptionOccurred() )
|
||||
throwOutOfMem(jenv);
|
||||
|
@ -480,38 +480,6 @@ JNIEXPORT jbyteArray JNICALL Java_com_apple_foundationdb_FutureKey_FutureKey_1ge
|
|||
return result;
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL Java_com_apple_foundationdb_FutureCluster_FutureCluster_1get(JNIEnv *jenv, jobject, jlong future) {
|
||||
if( !future ) {
|
||||
throwParamNotNull(jenv);
|
||||
return 0;
|
||||
}
|
||||
FDBFuture *f = (FDBFuture *)future;
|
||||
|
||||
FDBCluster *cluster;
|
||||
fdb_error_t err = fdb_future_get_cluster(f, &cluster);
|
||||
if( err ) {
|
||||
safeThrow( jenv, getThrowable( jenv, err ) );
|
||||
return 0;
|
||||
}
|
||||
return (jlong)cluster;
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL Java_com_apple_foundationdb_FutureDatabase_FutureDatabase_1get(JNIEnv *jenv, jobject, jlong future) {
|
||||
if( !future ) {
|
||||
throwParamNotNull(jenv);
|
||||
return 0;
|
||||
}
|
||||
FDBFuture *f = (FDBFuture *)future;
|
||||
|
||||
FDBDatabase *database;
|
||||
fdb_error_t err = fdb_future_get_database(f, &database);
|
||||
if( err ) {
|
||||
safeThrow( jenv, getThrowable( jenv, err ) );
|
||||
return 0;
|
||||
}
|
||||
return (jlong)database;
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL Java_com_apple_foundationdb_FDBDatabase_Database_1createTransaction(JNIEnv *jenv, jobject, jlong dbPtr) {
|
||||
if( !dbPtr ) {
|
||||
throwParamNotNull(jenv);
|
||||
|
@ -541,11 +509,11 @@ JNIEXPORT void JNICALL Java_com_apple_foundationdb_FDBDatabase_Database_1setOpti
|
|||
return;
|
||||
}
|
||||
FDBDatabase *c = (FDBDatabase *)dPtr;
|
||||
uint8_t *barr = NULL;
|
||||
uint8_t *barr = nullptr;
|
||||
int size = 0;
|
||||
|
||||
if(value != 0) {
|
||||
barr = (uint8_t *)jenv->GetByteArrayElements( value, NULL );
|
||||
if(value != JNI_NULL) {
|
||||
barr = (uint8_t *)jenv->GetByteArrayElements( value, JNI_NULL );
|
||||
if (!barr) {
|
||||
throwRuntimeEx( jenv, "Error getting handle to native resources" );
|
||||
return;
|
||||
|
@ -553,7 +521,7 @@ JNIEXPORT void JNICALL Java_com_apple_foundationdb_FDBDatabase_Database_1setOpti
|
|||
size = jenv->GetArrayLength( value );
|
||||
}
|
||||
fdb_error_t err = fdb_database_set_option( c, (FDBDatabaseOption)code, barr, size );
|
||||
if(value != 0)
|
||||
if(value != JNI_NULL)
|
||||
jenv->ReleaseByteArrayElements( value, (jbyte *)barr, JNI_ABORT );
|
||||
if( err ) {
|
||||
safeThrow( jenv, getThrowable( jenv, err ) );
|
||||
|
@ -564,69 +532,28 @@ JNIEXPORT jboolean JNICALL Java_com_apple_foundationdb_FDB_Error_1predicate(JNIE
|
|||
return (jboolean)fdb_error_predicate(predicate, code);
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL Java_com_apple_foundationdb_FDB_Cluster_1create(JNIEnv *jenv, jobject, jstring clusterFileName) {
|
||||
const char* fileName = 0;
|
||||
if(clusterFileName != 0) {
|
||||
fileName = jenv->GetStringUTFChars(clusterFileName, 0);
|
||||
if( jenv->ExceptionOccurred() )
|
||||
JNIEXPORT jlong JNICALL Java_com_apple_foundationdb_FDB_Database_1create(JNIEnv *jenv, jobject, jstring clusterFileName) {
|
||||
const char* fileName = nullptr;
|
||||
if(clusterFileName != JNI_NULL) {
|
||||
fileName = jenv->GetStringUTFChars(clusterFileName, JNI_NULL);
|
||||
if(jenv->ExceptionOccurred()) {
|
||||
return 0;
|
||||
}
|
||||
FDBFuture *cluster = fdb_create_cluster( fileName );
|
||||
if(clusterFileName != 0)
|
||||
jenv->ReleaseStringUTFChars( clusterFileName, fileName );
|
||||
return (jlong)cluster;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_apple_foundationdb_Cluster_Cluster_1setOption(JNIEnv *jenv, jobject, jlong cPtr, jint code, jbyteArray value) {
|
||||
if( !cPtr ) {
|
||||
throwParamNotNull(jenv);
|
||||
return;
|
||||
}
|
||||
FDBCluster *c = (FDBCluster *)cPtr;
|
||||
uint8_t *barr = NULL;
|
||||
int size = 0;
|
||||
|
||||
if(value != 0) {
|
||||
barr = (uint8_t *)jenv->GetByteArrayElements( value, NULL );
|
||||
if (!barr) {
|
||||
throwRuntimeEx( jenv, "Error getting handle to native resources" );
|
||||
return;
|
||||
}
|
||||
size = jenv->GetArrayLength( value );
|
||||
}
|
||||
fdb_error_t err = fdb_cluster_set_option( c, (FDBClusterOption)code, barr, size );
|
||||
if(value != 0)
|
||||
jenv->ReleaseByteArrayElements( value, (jbyte *)barr, JNI_ABORT );
|
||||
if( err ) {
|
||||
safeThrow( jenv, getThrowable( jenv, err ) );
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_apple_foundationdb_Cluster_Cluster_1dispose(JNIEnv *jenv, jobject, jlong cPtr) {
|
||||
if( !cPtr ) {
|
||||
throwParamNotNull(jenv);
|
||||
return;
|
||||
}
|
||||
fdb_cluster_destroy( (FDBCluster *)cPtr );
|
||||
}
|
||||
FDBDatabase *db;
|
||||
fdb_error_t err = fdb_create_database(fileName, &db);
|
||||
|
||||
JNIEXPORT jlong JNICALL Java_com_apple_foundationdb_Cluster_Cluster_1createDatabase(JNIEnv *jenv, jobject, jlong cPtr, jbyteArray dbNameBytes) {
|
||||
if( !cPtr || !dbNameBytes ) {
|
||||
throwParamNotNull(jenv);
|
||||
return 0;
|
||||
if(clusterFileName != JNI_NULL) {
|
||||
jenv->ReleaseStringUTFChars(clusterFileName, fileName);
|
||||
}
|
||||
FDBCluster *cluster = (FDBCluster *)cPtr;
|
||||
|
||||
uint8_t *barr = (uint8_t *)jenv->GetByteArrayElements( dbNameBytes, NULL );
|
||||
if (!barr) {
|
||||
throwRuntimeEx( jenv, "Error getting handle to native resources" );
|
||||
if(err) {
|
||||
safeThrow(jenv, getThrowable(jenv, err));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int size = jenv->GetArrayLength( dbNameBytes );
|
||||
FDBFuture * f = fdb_cluster_create_database( cluster, barr, size );
|
||||
jenv->ReleaseByteArrayElements( dbNameBytes, (jbyte *)barr, JNI_ABORT );
|
||||
return (jlong)f;
|
||||
return (jlong)db;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_apple_foundationdb_FDBTransaction_Transaction_1setVersion(JNIEnv *jenv, jobject, jlong tPtr, jlong version) {
|
||||
|
@ -655,7 +582,7 @@ JNIEXPORT jlong JNICALL Java_com_apple_foundationdb_FDBTransaction_Transaction_1
|
|||
}
|
||||
FDBTransaction *tr = (FDBTransaction *)tPtr;
|
||||
|
||||
uint8_t *barr = (uint8_t *)jenv->GetByteArrayElements( keyBytes, NULL );
|
||||
uint8_t *barr = (uint8_t *)jenv->GetByteArrayElements( keyBytes, JNI_NULL );
|
||||
if(!barr) {
|
||||
if( !jenv->ExceptionOccurred() )
|
||||
throwRuntimeEx( jenv, "Error getting handle to native resources" );
|
||||
|
@ -675,7 +602,7 @@ JNIEXPORT jlong JNICALL Java_com_apple_foundationdb_FDBTransaction_Transaction_1
|
|||
}
|
||||
FDBTransaction *tr = (FDBTransaction *)tPtr;
|
||||
|
||||
uint8_t *barr = (uint8_t *)jenv->GetByteArrayElements( keyBytes, NULL );
|
||||
uint8_t *barr = (uint8_t *)jenv->GetByteArrayElements( keyBytes, JNI_NULL );
|
||||
if(!barr) {
|
||||
if( !jenv->ExceptionOccurred() )
|
||||
throwRuntimeEx( jenv, "Error getting handle to native resources" );
|
||||
|
@ -697,14 +624,14 @@ JNIEXPORT jlong JNICALL Java_com_apple_foundationdb_FDBTransaction_Transaction_1
|
|||
}
|
||||
FDBTransaction *tr = (FDBTransaction *)tPtr;
|
||||
|
||||
uint8_t *barrBegin = (uint8_t *)jenv->GetByteArrayElements( keyBeginBytes, NULL );
|
||||
uint8_t *barrBegin = (uint8_t *)jenv->GetByteArrayElements( keyBeginBytes, JNI_NULL );
|
||||
if (!barrBegin) {
|
||||
if( !jenv->ExceptionOccurred() )
|
||||
throwRuntimeEx( jenv, "Error getting handle to native resources" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t *barrEnd = (uint8_t *)jenv->GetByteArrayElements( keyEndBytes, NULL );
|
||||
uint8_t *barrEnd = (uint8_t *)jenv->GetByteArrayElements( keyEndBytes, JNI_NULL );
|
||||
if (!barrEnd) {
|
||||
jenv->ReleaseByteArrayElements( keyBeginBytes, (jbyte *)barrBegin, JNI_ABORT );
|
||||
if( !jenv->ExceptionOccurred() )
|
||||
|
@ -728,14 +655,14 @@ JNIEXPORT void JNICALL Java_com_apple_foundationdb_FDBTransaction_Transaction_1s
|
|||
}
|
||||
FDBTransaction *tr = (FDBTransaction *)tPtr;
|
||||
|
||||
uint8_t *barrKey = (uint8_t *)jenv->GetByteArrayElements( keyBytes, NULL );
|
||||
uint8_t *barrKey = (uint8_t *)jenv->GetByteArrayElements( keyBytes, JNI_NULL );
|
||||
if (!barrKey) {
|
||||
if( !jenv->ExceptionOccurred() )
|
||||
throwRuntimeEx( jenv, "Error getting handle to native resources" );
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t *barrValue = (uint8_t *)jenv->GetByteArrayElements( valueBytes, NULL );
|
||||
uint8_t *barrValue = (uint8_t *)jenv->GetByteArrayElements( valueBytes, JNI_NULL );
|
||||
if (!barrValue) {
|
||||
jenv->ReleaseByteArrayElements( keyBytes, (jbyte *)barrKey, JNI_ABORT );
|
||||
if( !jenv->ExceptionOccurred() )
|
||||
|
@ -757,7 +684,7 @@ JNIEXPORT void JNICALL Java_com_apple_foundationdb_FDBTransaction_Transaction_1c
|
|||
}
|
||||
FDBTransaction *tr = (FDBTransaction *)tPtr;
|
||||
|
||||
uint8_t *barr = (uint8_t *)jenv->GetByteArrayElements( keyBytes, NULL );
|
||||
uint8_t *barr = (uint8_t *)jenv->GetByteArrayElements( keyBytes, JNI_NULL );
|
||||
if (!barr) {
|
||||
if( !jenv->ExceptionOccurred() )
|
||||
throwRuntimeEx( jenv, "Error getting handle to native resources" );
|
||||
|
@ -775,14 +702,14 @@ JNIEXPORT void JNICALL Java_com_apple_foundationdb_FDBTransaction_Transaction_1c
|
|||
}
|
||||
FDBTransaction *tr = (FDBTransaction *)tPtr;
|
||||
|
||||
uint8_t *barrKeyBegin = (uint8_t *)jenv->GetByteArrayElements( keyBeginBytes, NULL );
|
||||
uint8_t *barrKeyBegin = (uint8_t *)jenv->GetByteArrayElements( keyBeginBytes, JNI_NULL );
|
||||
if (!barrKeyBegin) {
|
||||
if( !jenv->ExceptionOccurred() )
|
||||
throwRuntimeEx( jenv, "Error getting handle to native resources" );
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t *barrKeyEnd = (uint8_t *)jenv->GetByteArrayElements( keyEndBytes, NULL );
|
||||
uint8_t *barrKeyEnd = (uint8_t *)jenv->GetByteArrayElements( keyEndBytes, JNI_NULL );
|
||||
if (!barrKeyEnd) {
|
||||
jenv->ReleaseByteArrayElements( keyBeginBytes, (jbyte *)barrKeyBegin, JNI_ABORT );
|
||||
if( !jenv->ExceptionOccurred() )
|
||||
|
@ -805,14 +732,14 @@ JNIEXPORT void JNICALL Java_com_apple_foundationdb_FDBTransaction_Transaction_1m
|
|||
}
|
||||
FDBTransaction *tr = (FDBTransaction *)tPtr;
|
||||
|
||||
uint8_t *barrKey = (uint8_t *)jenv->GetByteArrayElements( key, NULL );
|
||||
uint8_t *barrKey = (uint8_t *)jenv->GetByteArrayElements( key, JNI_NULL );
|
||||
if (!barrKey) {
|
||||
if( !jenv->ExceptionOccurred() )
|
||||
throwRuntimeEx( jenv, "Error getting handle to native resources" );
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t *barrValue = (uint8_t *)jenv->GetByteArrayElements( value, NULL );
|
||||
uint8_t *barrValue = (uint8_t *)jenv->GetByteArrayElements( value, JNI_NULL );
|
||||
if (!barrValue) {
|
||||
jenv->ReleaseByteArrayElements( key, (jbyte *)barrKey, JNI_ABORT );
|
||||
if( !jenv->ExceptionOccurred() )
|
||||
|
@ -845,11 +772,11 @@ JNIEXPORT void JNICALL Java_com_apple_foundationdb_FDBTransaction_Transaction_1s
|
|||
return;
|
||||
}
|
||||
FDBTransaction *tr = (FDBTransaction *)tPtr;
|
||||
uint8_t *barr = NULL;
|
||||
uint8_t *barr = nullptr;
|
||||
int size = 0;
|
||||
|
||||
if(value != 0) {
|
||||
barr = (uint8_t *)jenv->GetByteArrayElements( value, NULL );
|
||||
if(value != JNI_NULL) {
|
||||
barr = (uint8_t *)jenv->GetByteArrayElements( value, JNI_NULL );
|
||||
if (!barr) {
|
||||
if( !jenv->ExceptionOccurred() )
|
||||
throwRuntimeEx( jenv, "Error getting handle to native resources" );
|
||||
|
@ -858,7 +785,7 @@ JNIEXPORT void JNICALL Java_com_apple_foundationdb_FDBTransaction_Transaction_1s
|
|||
size = jenv->GetArrayLength( value );
|
||||
}
|
||||
fdb_error_t err = fdb_transaction_set_option( tr, (FDBTransactionOption)code, barr, size );
|
||||
if(value != 0)
|
||||
if(value != JNI_NULL)
|
||||
jenv->ReleaseByteArrayElements( value, (jbyte *)barr, JNI_ABORT );
|
||||
if( err ) {
|
||||
safeThrow( jenv, getThrowable( jenv, err ) );
|
||||
|
@ -897,7 +824,7 @@ JNIEXPORT jlong JNICALL Java_com_apple_foundationdb_FDBTransaction_Transaction_1
|
|||
}
|
||||
FDBTransaction *tr = (FDBTransaction *)tPtr;
|
||||
|
||||
uint8_t *barr = (uint8_t *)jenv->GetByteArrayElements( key, NULL );
|
||||
uint8_t *barr = (uint8_t *)jenv->GetByteArrayElements( key, JNI_NULL );
|
||||
if (!barr) {
|
||||
if( !jenv->ExceptionOccurred() )
|
||||
throwRuntimeEx( jenv, "Error getting handle to native resources" );
|
||||
|
@ -944,7 +871,7 @@ JNIEXPORT jlong JNICALL Java_com_apple_foundationdb_FDBTransaction_Transaction_1
|
|||
}
|
||||
FDBTransaction *tr = (FDBTransaction *)tPtr;
|
||||
|
||||
uint8_t *barr = (uint8_t *)jenv->GetByteArrayElements( key, NULL );
|
||||
uint8_t *barr = (uint8_t *)jenv->GetByteArrayElements( key, JNI_NULL );
|
||||
if (!barr) {
|
||||
if( !jenv->ExceptionOccurred() )
|
||||
throwRuntimeEx( jenv, "Error getting handle to native resources" );
|
||||
|
@ -973,7 +900,7 @@ JNIEXPORT void JNICALL Java_com_apple_foundationdb_FDBTransaction_Transaction_1a
|
|||
}
|
||||
FDBTransaction *tr = (FDBTransaction *)tPtr;
|
||||
|
||||
uint8_t *begin_barr = (uint8_t *)jenv->GetByteArrayElements( keyBegin, NULL );
|
||||
uint8_t *begin_barr = (uint8_t *)jenv->GetByteArrayElements( keyBegin, JNI_NULL );
|
||||
if (!begin_barr) {
|
||||
if( !jenv->ExceptionOccurred() )
|
||||
throwRuntimeEx( jenv, "Error getting handle to native resources" );
|
||||
|
@ -981,7 +908,7 @@ JNIEXPORT void JNICALL Java_com_apple_foundationdb_FDBTransaction_Transaction_1a
|
|||
}
|
||||
int begin_size = jenv->GetArrayLength( keyBegin );
|
||||
|
||||
uint8_t *end_barr = (uint8_t *)jenv->GetByteArrayElements( keyEnd, NULL );
|
||||
uint8_t *end_barr = (uint8_t *)jenv->GetByteArrayElements( keyEnd, JNI_NULL );
|
||||
if (!end_barr) {
|
||||
jenv->ReleaseByteArrayElements( keyBegin, (jbyte *)begin_barr, JNI_ABORT );
|
||||
if( !jenv->ExceptionOccurred() )
|
||||
|
@ -1026,10 +953,10 @@ JNIEXPORT void JNICALL Java_com_apple_foundationdb_FDB_Select_1API_1version(JNIE
|
|||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_apple_foundationdb_FDB_Network_1setOption(JNIEnv *jenv, jobject, jint code, jbyteArray value) {
|
||||
uint8_t *barr = NULL;
|
||||
uint8_t *barr = nullptr;
|
||||
int size = 0;
|
||||
if(value != 0) {
|
||||
barr = (uint8_t *)jenv->GetByteArrayElements( value, NULL );
|
||||
if(value != JNI_NULL) {
|
||||
barr = (uint8_t *)jenv->GetByteArrayElements( value, JNI_NULL );
|
||||
if (!barr) {
|
||||
if( !jenv->ExceptionOccurred() )
|
||||
throwRuntimeEx( jenv, "Error getting handle to native resources" );
|
||||
|
@ -1038,7 +965,7 @@ JNIEXPORT void JNICALL Java_com_apple_foundationdb_FDB_Network_1setOption(JNIEnv
|
|||
size = jenv->GetArrayLength( value );
|
||||
}
|
||||
fdb_error_t err = fdb_network_set_option((FDBNetworkOption)code, barr, size);
|
||||
if(value != 0)
|
||||
if(value != JNI_NULL)
|
||||
jenv->ReleaseByteArrayElements( value, (jbyte *)barr, JNI_ABORT );
|
||||
if( err ) {
|
||||
safeThrow( jenv, getThrowable( jenv, err ) );
|
||||
|
@ -1060,7 +987,7 @@ JNIEXPORT void JNICALL Java_com_apple_foundationdb_FDB_Network_1run(JNIEnv *jenv
|
|||
return;
|
||||
}
|
||||
|
||||
fdb_error_t hookErr = fdb_add_network_thread_completion_hook( &detachIfExternalThread, NULL );
|
||||
fdb_error_t hookErr = fdb_add_network_thread_completion_hook( &detachIfExternalThread, nullptr );
|
||||
if( hookErr ) {
|
||||
safeThrow( jenv, getThrowable( jenv, hookErr ) );
|
||||
}
|
||||
|
|
|
@ -20,33 +20,29 @@
|
|||
|
||||
package com.apple.foundationdb;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
* The {@code Cluster} represents a connection to a physical set of cooperating machines
|
||||
* running FoundationDB. A {@code Cluster} is opened with a reference to a cluster file.<br>
|
||||
* running FoundationDB. A {@code Cluster} is opened with a reference to a cluster file.
|
||||
*
|
||||
* This class is deprecated. Use {@link FDB#open} to open a {@link Database} directly<br>
|
||||
* <br>
|
||||
* <b>Note:</b> {@code Cluster} objects must be {@link #close closed} when no longer in use
|
||||
* in order to free any associated resources.
|
||||
*/
|
||||
@Deprecated
|
||||
public class Cluster extends NativeObjectWrapper {
|
||||
private ClusterOptions options;
|
||||
private final Executor executor;
|
||||
private final String clusterFile;
|
||||
|
||||
private static final Charset UTF8 = Charset.forName("UTF-8");
|
||||
protected Cluster(String clusterFile, Executor executor) {
|
||||
super(0);
|
||||
|
||||
protected Cluster(long cPtr, Executor executor) {
|
||||
super(cPtr);
|
||||
this.executor = executor;
|
||||
this.options = new ClusterOptions((code, parameter) -> {
|
||||
pointerReadLock.lock();
|
||||
try {
|
||||
Cluster_setOption(getPtr(), code, parameter);
|
||||
} finally {
|
||||
pointerReadLock.unlock();
|
||||
}
|
||||
});
|
||||
this.options = new ClusterOptions((code, parameter) -> {});
|
||||
this.clusterFile = clusterFile;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -59,19 +55,8 @@ public class Cluster extends NativeObjectWrapper {
|
|||
return options;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
try {
|
||||
checkUnclosed("Cluster");
|
||||
close();
|
||||
}
|
||||
finally {
|
||||
super.finalize();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a connection to a specific database on an <i>FDB</i> cluster.
|
||||
* Creates a connection to the database on an <i>FDB</i> cluster.
|
||||
*
|
||||
* @return a {@code Future} that will be set to a {@code Database} upon
|
||||
* successful connection.
|
||||
|
@ -81,7 +66,7 @@ public class Cluster extends NativeObjectWrapper {
|
|||
}
|
||||
|
||||
/**
|
||||
* Creates a connection to a specific database on an <i>FDB</i> cluster.
|
||||
* Creates a connection to the database on an <i>FDB</i> cluster.
|
||||
*
|
||||
* @param e the {@link Executor} to use when executing asynchronous callbacks for the database
|
||||
*
|
||||
|
@ -89,22 +74,9 @@ public class Cluster extends NativeObjectWrapper {
|
|||
* successful connection.
|
||||
*/
|
||||
public Database openDatabase(Executor e) throws FDBException {
|
||||
FutureDatabase futureDatabase;
|
||||
pointerReadLock.lock();
|
||||
try {
|
||||
futureDatabase = new FutureDatabase(Cluster_createDatabase(getPtr(), "DB".getBytes(UTF8)), e);
|
||||
} finally {
|
||||
pointerReadLock.unlock();
|
||||
}
|
||||
return futureDatabase.join();
|
||||
return FDB.instance().open(clusterFile, e);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void closeInternal(long cPtr) {
|
||||
Cluster_dispose(cPtr);
|
||||
}
|
||||
|
||||
private native void Cluster_dispose(long cPtr);
|
||||
private native long Cluster_createDatabase(long cPtr, byte[] dbName);
|
||||
private native void Cluster_setOption(long cPtr, int code, byte[] value) throws FDBException;
|
||||
protected void closeInternal(long cPtr) {}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
/*
|
||||
* FutureCluster.java
|
||||
* ClusterOptions.java
|
||||
*
|
||||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
* Copyright 2013-2019 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -20,21 +20,14 @@
|
|||
|
||||
package com.apple.foundationdb;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
class FutureCluster extends NativeFuture<Cluster> {
|
||||
private final Executor executor;
|
||||
|
||||
protected FutureCluster(long cPtr, Executor executor) {
|
||||
super(cPtr);
|
||||
this.executor = executor;
|
||||
registerMarshalCallback(executor);
|
||||
/**
|
||||
* A set of options that can be set on a {@link Cluster}.
|
||||
*
|
||||
* @deprecated There are no cluster options.
|
||||
*/
|
||||
@Deprecated
|
||||
public class ClusterOptions extends OptionsSet {
|
||||
public ClusterOptions( OptionConsumer consumer ) {
|
||||
super(consumer);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Cluster getIfDone_internal(long cPtr) throws FDBException {
|
||||
return new Cluster(FutureCluster_get(cPtr), executor);
|
||||
}
|
||||
|
||||
private native long FutureCluster_get(long cPtr) throws FDBException;
|
||||
}
|
|
@ -26,7 +26,6 @@ import java.util.function.Function;
|
|||
|
||||
/**
|
||||
* A mutable, lexicographically ordered mapping from binary keys to binary values.
|
||||
* A {@code Database} is stored on a FoundationDB {@link Cluster}.
|
||||
* {@link Transaction}s are used to manipulate data within a single
|
||||
* {@code Database} -- multiple, concurrent
|
||||
* {@code Transaction}s on a {@code Database} enforce <b>ACID</b> properties.<br>
|
||||
|
|
|
@ -54,8 +54,8 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||
* to call {@link #open}.
|
||||
* <br>
|
||||
* <h3>Client networking</h3>
|
||||
* The network is started either implicitly with a call to a variant of {@link #open()} or
|
||||
* {@link #createCluster()}, or started explicitly with a call to {@link #startNetwork()}.
|
||||
* The network is started either implicitly with a call to a variant of {@link #open()}
|
||||
* or started explicitly with a call to {@link #startNetwork()}.
|
||||
* <br>
|
||||
*
|
||||
*/
|
||||
|
@ -114,8 +114,8 @@ public class FDB {
|
|||
* Returns a set of options that can be set on a the FoundationDB API. Generally,
|
||||
* these options to the top level of the API affect the networking engine and
|
||||
* therefore must be set before the network engine is started. The network is started
|
||||
* by calls to {@link #startNetwork()} and implicitly by calls to {@link #open()} and
|
||||
* {@link #createCluster()} (and their respective variants).
|
||||
* by calls to {@link #startNetwork()} or implicitly by a call to {@link #open()} and
|
||||
* and its variants.
|
||||
*
|
||||
* @return a set of options affecting this instance of the FoundationDB API
|
||||
*/
|
||||
|
@ -218,11 +218,14 @@ public class FDB {
|
|||
* If the FoundationDB network has not been started, it will be started in the course of this call
|
||||
* as if {@link FDB#startNetwork()} had been called.
|
||||
*
|
||||
* @deprecated Use {@link #open()} instead.
|
||||
*
|
||||
* @return a {@code CompletableFuture} that will be set to a FoundationDB {@code Cluster}.
|
||||
*
|
||||
* @throws FDBException on errors encountered starting the FoundationDB networking engine
|
||||
* @throws IllegalStateException if the network had been previously stopped
|
||||
*/
|
||||
@Deprecated
|
||||
public Cluster createCluster() throws IllegalStateException, FDBException {
|
||||
return createCluster(null);
|
||||
}
|
||||
|
@ -232,6 +235,8 @@ public class FDB {
|
|||
* has not been started, it will be started in the course of this call as if
|
||||
* {@link #startNetwork()} had been called.
|
||||
*
|
||||
* @deprecated Use {@link #open(String)} instead.
|
||||
*
|
||||
* @param clusterFilePath the
|
||||
* <a href="/foundationdb/administration.html#foundationdb-cluster-file" target="_blank">cluster file</a>
|
||||
* defining the FoundationDB cluster. This can be {@code null} if the
|
||||
|
@ -243,6 +248,7 @@ public class FDB {
|
|||
* @throws FDBException on errors encountered starting the FoundationDB networking engine
|
||||
* @throws IllegalStateException if the network had been previously stopped
|
||||
*/
|
||||
@Deprecated
|
||||
public Cluster createCluster(String clusterFilePath) throws IllegalStateException, FDBException {
|
||||
return createCluster(clusterFilePath, DEFAULT_EXECUTOR);
|
||||
}
|
||||
|
@ -253,6 +259,8 @@ public class FDB {
|
|||
* {@link Executor} will be used as the default for the execution of all callbacks that
|
||||
* are produced from using the resulting {@link Cluster}.
|
||||
*
|
||||
* @deprecated Use {@link #open(String, Executor)} instead.
|
||||
*
|
||||
* @param clusterFilePath the
|
||||
* <a href="/foundationdb/administration.html#foundationdb-cluster-file" target="_blank">cluster file</a>
|
||||
* defining the FoundationDB cluster. This can be {@code null} if the
|
||||
|
@ -265,16 +273,10 @@ public class FDB {
|
|||
* @throws FDBException on errors encountered starting the FoundationDB networking engine
|
||||
* @throws IllegalStateException if the network had been previously stopped
|
||||
*/
|
||||
@Deprecated
|
||||
public Cluster createCluster(String clusterFilePath, Executor e)
|
||||
throws FDBException, IllegalStateException {
|
||||
FutureCluster f;
|
||||
synchronized (this) {
|
||||
if (!isConnected()) {
|
||||
startNetwork();
|
||||
}
|
||||
f = new FutureCluster(Cluster_create(clusterFilePath), e);
|
||||
}
|
||||
return f.join();
|
||||
return new Cluster(clusterFilePath, e);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -318,26 +320,21 @@ public class FDB {
|
|||
* @return a {@code CompletableFuture} that will be set to a FoundationDB {@link Database}
|
||||
*/
|
||||
public Database open(String clusterFilePath, Executor e) throws FDBException {
|
||||
FutureCluster f;
|
||||
synchronized (this) {
|
||||
if (!isConnected()) {
|
||||
synchronized(this) {
|
||||
if(!isConnected()) {
|
||||
startNetwork();
|
||||
}
|
||||
f = new FutureCluster(Cluster_create(clusterFilePath), e);
|
||||
}
|
||||
Cluster c = f.join();
|
||||
Database db = c.openDatabase(e);
|
||||
c.close();
|
||||
|
||||
return db;
|
||||
return new FDBDatabase(Database_create(clusterFilePath), e);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes networking. Can only be called once. This version of
|
||||
* {@code startNetwork()} will create a new thread and execute the networking
|
||||
* event loop on that thread. This method is called upon {@link Database} or
|
||||
* {@link Cluster} creation by default if the network has not yet
|
||||
* been started. If one wishes to control what thread the network runs on,
|
||||
* event loop on that thread. This method is called upon {@link Database}
|
||||
* creation by default if the network has not yet been started. If one
|
||||
* wishes to control what thread the network runs on,
|
||||
* one should use the version of {@link #startNetwork(Executor) startNetwork()}
|
||||
* that takes an {@link Executor}.<br>
|
||||
* <br>
|
||||
|
@ -472,5 +469,5 @@ public class FDB {
|
|||
|
||||
private native boolean Error_predicate(int predicate, int code);
|
||||
|
||||
private native long Cluster_create(String clusterFileName);
|
||||
private native long Database_create(String clusterFilePath) throws FDBException;
|
||||
}
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
/*
|
||||
* FutureDatabase.java
|
||||
*
|
||||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.apple.foundationdb;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
class FutureDatabase extends NativeFuture<Database> {
|
||||
private final Executor executor;
|
||||
|
||||
FutureDatabase(long cPtr, Executor executor) {
|
||||
super(cPtr);
|
||||
this.executor = executor;
|
||||
registerMarshalCallback(executor);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Database getIfDone_internal(long cPtr) throws FDBException {
|
||||
return new FDBDatabase(FutureDatabase_get(cPtr), executor);
|
||||
}
|
||||
|
||||
private native long FutureDatabase_get(long cPtr) throws FDBException;
|
||||
}
|
|
@ -33,7 +33,6 @@ import java.util.Map;
|
|||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Function;
|
||||
|
||||
import com.apple.foundationdb.Cluster;
|
||||
import com.apple.foundationdb.Database;
|
||||
import com.apple.foundationdb.FDB;
|
||||
import com.apple.foundationdb.FDBException;
|
||||
|
@ -723,9 +722,7 @@ public class AsyncStackTester {
|
|||
throw new IllegalStateException("API version not correctly set to " + apiVersion);
|
||||
}
|
||||
//ExecutorService executor = Executors.newFixedThreadPool(2);
|
||||
Cluster cl = fdb.createCluster(args.length > 2 ? args[2] : null);
|
||||
|
||||
Database db = cl.openDatabase();
|
||||
Database db = fdb.open(args.length > 2 ? args[2] : null);
|
||||
|
||||
Context c = new AsynchronousContext(db, prefix);
|
||||
//System.out.println("Starting test...");
|
||||
|
|
|
@ -81,17 +81,16 @@ def api_version(ver):
|
|||
elif err != 0:
|
||||
raise RuntimeError('FoundationDB API error')
|
||||
|
||||
fdb.impl.init_c_api()
|
||||
|
||||
list = (
|
||||
'FDBError',
|
||||
'predicates',
|
||||
'Future',
|
||||
'Cluster',
|
||||
'Database',
|
||||
'Transaction',
|
||||
'KeyValue',
|
||||
'KeySelector',
|
||||
'init',
|
||||
'create_cluster',
|
||||
'open',
|
||||
'transactional',
|
||||
'options',
|
||||
|
@ -100,6 +99,12 @@ def api_version(ver):
|
|||
|
||||
_add_symbols(fdb.impl, list)
|
||||
|
||||
if ver < 610:
|
||||
globals()["init"] = getattr(fdb.impl, "init")
|
||||
globals()["open"] = getattr(fdb.impl, "open_v609")
|
||||
globals()["create_cluster"] = getattr(fdb.impl, "create_cluster")
|
||||
globals()["Cluster"] = getattr(fdb.impl, "Cluster")
|
||||
|
||||
if ver > 22:
|
||||
import fdb.locality
|
||||
|
||||
|
|
|
@ -51,11 +51,6 @@ class _ErrorPredicates(object):
|
|||
self._parent = parent
|
||||
|
||||
|
||||
class _ClusterOptions(object):
|
||||
def __init__(self, cluster):
|
||||
self._parent = weakref.proxy(cluster)
|
||||
|
||||
|
||||
class _DatabaseOptions(object):
|
||||
def __init__(self, db):
|
||||
self._parent = weakref.proxy(db)
|
||||
|
@ -158,7 +153,7 @@ def fill_operations():
|
|||
add_operation("bit_" + fname, v)
|
||||
|
||||
|
||||
for scope in ['ClusterOption', 'DatabaseOption', 'TransactionOption', 'NetworkOption']:
|
||||
for scope in ['DatabaseOption', 'TransactionOption', 'NetworkOption']:
|
||||
fill_options(scope)
|
||||
|
||||
fill_options('ErrorPredicate', True)
|
||||
|
@ -600,11 +595,6 @@ class Future(_FDBBase):
|
|||
def block_until_ready(self):
|
||||
self.capi.fdb_future_block_until_ready(self.fpointer)
|
||||
|
||||
# Depending on the event_model, block_until_ready may be remapped to do something asynchronous or
|
||||
# just fail. really_block_until_ready() is always fdb_future_block_until_ready() and is used e.g.
|
||||
# for database and cluster futures that should always be available very quickly
|
||||
really_block_until_ready = block_until_ready
|
||||
|
||||
def on_ready(self, callback):
|
||||
def cb_and_delref(ignore):
|
||||
_unpin_callback(cbfunc[0])
|
||||
|
@ -878,7 +868,7 @@ class FormerFuture(_FDBBase):
|
|||
pass
|
||||
|
||||
|
||||
class Database(FormerFuture):
|
||||
class Database(_FDBBase):
|
||||
def __init__(self, dpointer):
|
||||
self.dpointer = dpointer
|
||||
self.options = _DatabaseOptions(self)
|
||||
|
@ -1097,33 +1087,25 @@ class Database(FormerFuture):
|
|||
fill_operations()
|
||||
|
||||
|
||||
class Cluster(FormerFuture):
|
||||
def __init__(self, cpointer):
|
||||
self.cpointer = cpointer
|
||||
self.options = _ClusterOptions(self)
|
||||
|
||||
def __del__(self):
|
||||
# print('Destroying cluster 0x%x' % self.cpointer)
|
||||
self.capi.fdb_cluster_destroy(self.cpointer)
|
||||
class Cluster(_FDBBase):
|
||||
def __init__(self, cluster_file):
|
||||
self.cluster_file = cluster_file
|
||||
self.options = None
|
||||
|
||||
def open_database(self, name):
|
||||
name = paramToBytes(name)
|
||||
f = Future(self.capi.fdb_cluster_create_database(self.cpointer, name, len(name)))
|
||||
f.really_block_until_ready()
|
||||
dpointer = ctypes.c_void_p()
|
||||
self.capi.fdb_future_get_database(f.fpointer, ctypes.byref(dpointer))
|
||||
return Database(dpointer)
|
||||
if name != b'DB':
|
||||
raise FDBError(2013) # invalid_database_name
|
||||
|
||||
def _set_option(self, option, param, length):
|
||||
self.capi.fdb_cluster_set_option(self.cpointer, option, param, length)
|
||||
return create_database(self.cluster_file)
|
||||
|
||||
|
||||
def create_database(cluster_file=None):
|
||||
pointer = ctypes.c_void_p()
|
||||
_FDBBase.capi.fdb_create_database(optionalParamToBytes(cluster_file)[0], ctypes.byref(pointer))
|
||||
return Database(pointer)
|
||||
|
||||
def create_cluster(cluster_file=None):
|
||||
f = Future(_FDBBase.capi.fdb_create_cluster(optionalParamToBytes(cluster_file)[0]))
|
||||
cpointer = ctypes.c_void_p()
|
||||
f.really_block_until_ready()
|
||||
_FDBBase.capi.fdb_future_get_cluster(f.fpointer, ctypes.byref(cpointer))
|
||||
return Cluster(cpointer)
|
||||
return Cluster(cluster_file)
|
||||
|
||||
|
||||
class KeySelector(object):
|
||||
|
@ -1303,176 +1285,160 @@ def optionalParamToBytes(v):
|
|||
|
||||
_FDBBase.capi = _capi
|
||||
|
||||
_capi.fdb_select_api_version_impl.argtypes = [ctypes.c_int, ctypes.c_int]
|
||||
_capi.fdb_select_api_version_impl.restype = ctypes.c_int
|
||||
def init_c_api():
|
||||
_capi.fdb_select_api_version_impl.argtypes = [ctypes.c_int, ctypes.c_int]
|
||||
_capi.fdb_select_api_version_impl.restype = ctypes.c_int
|
||||
|
||||
_capi.fdb_get_error.argtypes = [ctypes.c_int]
|
||||
_capi.fdb_get_error.restype = ctypes.c_char_p
|
||||
_capi.fdb_get_error.argtypes = [ctypes.c_int]
|
||||
_capi.fdb_get_error.restype = ctypes.c_char_p
|
||||
|
||||
_capi.fdb_error_predicate.argtypes = [ctypes.c_int, ctypes.c_int]
|
||||
_capi.fdb_error_predicate.restype = ctypes.c_int
|
||||
_capi.fdb_error_predicate.argtypes = [ctypes.c_int, ctypes.c_int]
|
||||
_capi.fdb_error_predicate.restype = ctypes.c_int
|
||||
|
||||
_capi.fdb_setup_network.argtypes = []
|
||||
_capi.fdb_setup_network.restype = ctypes.c_int
|
||||
_capi.fdb_setup_network.errcheck = check_error_code
|
||||
_capi.fdb_setup_network.argtypes = []
|
||||
_capi.fdb_setup_network.restype = ctypes.c_int
|
||||
_capi.fdb_setup_network.errcheck = check_error_code
|
||||
|
||||
_capi.fdb_network_set_option.argtypes = [ctypes.c_int, ctypes.c_void_p, ctypes.c_int]
|
||||
_capi.fdb_network_set_option.restype = ctypes.c_int
|
||||
_capi.fdb_network_set_option.errcheck = check_error_code
|
||||
_capi.fdb_network_set_option.argtypes = [ctypes.c_int, ctypes.c_void_p, ctypes.c_int]
|
||||
_capi.fdb_network_set_option.restype = ctypes.c_int
|
||||
_capi.fdb_network_set_option.errcheck = check_error_code
|
||||
|
||||
_capi.fdb_run_network.argtypes = []
|
||||
_capi.fdb_run_network.restype = ctypes.c_int
|
||||
_capi.fdb_run_network.errcheck = check_error_code
|
||||
_capi.fdb_run_network.argtypes = []
|
||||
_capi.fdb_run_network.restype = ctypes.c_int
|
||||
_capi.fdb_run_network.errcheck = check_error_code
|
||||
|
||||
_capi.fdb_stop_network.argtypes = []
|
||||
_capi.fdb_stop_network.restype = ctypes.c_int
|
||||
_capi.fdb_stop_network.errcheck = check_error_code
|
||||
_capi.fdb_stop_network.argtypes = []
|
||||
_capi.fdb_stop_network.restype = ctypes.c_int
|
||||
_capi.fdb_stop_network.errcheck = check_error_code
|
||||
|
||||
_capi.fdb_future_destroy.argtypes = [ctypes.c_void_p]
|
||||
_capi.fdb_future_destroy.restype = None
|
||||
_capi.fdb_future_destroy.argtypes = [ctypes.c_void_p]
|
||||
_capi.fdb_future_destroy.restype = None
|
||||
|
||||
_capi.fdb_future_release_memory.argtypes = [ctypes.c_void_p]
|
||||
_capi.fdb_future_release_memory.restype = None
|
||||
_capi.fdb_future_release_memory.argtypes = [ctypes.c_void_p]
|
||||
_capi.fdb_future_release_memory.restype = None
|
||||
|
||||
_capi.fdb_future_cancel.argtypes = [ctypes.c_void_p]
|
||||
_capi.fdb_future_cancel.restype = None
|
||||
_capi.fdb_future_cancel.argtypes = [ctypes.c_void_p]
|
||||
_capi.fdb_future_cancel.restype = None
|
||||
|
||||
_capi.fdb_future_block_until_ready.argtypes = [ctypes.c_void_p]
|
||||
_capi.fdb_future_block_until_ready.restype = ctypes.c_int
|
||||
_capi.fdb_future_block_until_ready.errcheck = check_error_code
|
||||
_capi.fdb_future_block_until_ready.argtypes = [ctypes.c_void_p]
|
||||
_capi.fdb_future_block_until_ready.restype = ctypes.c_int
|
||||
_capi.fdb_future_block_until_ready.errcheck = check_error_code
|
||||
|
||||
_capi.fdb_future_is_ready.argtypes = [ctypes.c_void_p]
|
||||
_capi.fdb_future_is_ready.restype = ctypes.c_int
|
||||
_capi.fdb_future_is_ready.argtypes = [ctypes.c_void_p]
|
||||
_capi.fdb_future_is_ready.restype = ctypes.c_int
|
||||
|
||||
_CBFUNC = ctypes.CFUNCTYPE(None, ctypes.c_void_p)
|
||||
_CBFUNC = ctypes.CFUNCTYPE(None, ctypes.c_void_p)
|
||||
|
||||
_capi.fdb_future_set_callback.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p]
|
||||
_capi.fdb_future_set_callback.restype = int
|
||||
_capi.fdb_future_set_callback.errcheck = check_error_code
|
||||
_capi.fdb_future_set_callback.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p]
|
||||
_capi.fdb_future_set_callback.restype = int
|
||||
_capi.fdb_future_set_callback.errcheck = check_error_code
|
||||
|
||||
_capi.fdb_future_get_error.argtypes = [ctypes.c_void_p]
|
||||
_capi.fdb_future_get_error.restype = int
|
||||
_capi.fdb_future_get_error.errcheck = check_error_code
|
||||
_capi.fdb_future_get_error.argtypes = [ctypes.c_void_p]
|
||||
_capi.fdb_future_get_error.restype = int
|
||||
_capi.fdb_future_get_error.errcheck = check_error_code
|
||||
|
||||
_capi.fdb_future_get_version.argtypes = [ctypes.c_void_p, ctypes.POINTER(ctypes.c_int64)]
|
||||
_capi.fdb_future_get_version.restype = ctypes.c_int
|
||||
_capi.fdb_future_get_version.errcheck = check_error_code
|
||||
_capi.fdb_future_get_version.argtypes = [ctypes.c_void_p, ctypes.POINTER(ctypes.c_int64)]
|
||||
_capi.fdb_future_get_version.restype = ctypes.c_int
|
||||
_capi.fdb_future_get_version.errcheck = check_error_code
|
||||
|
||||
_capi.fdb_future_get_key.argtypes = [ctypes.c_void_p, ctypes.POINTER(ctypes.POINTER(ctypes.c_byte)),
|
||||
ctypes.POINTER(ctypes.c_int)]
|
||||
_capi.fdb_future_get_key.restype = ctypes.c_int
|
||||
_capi.fdb_future_get_key.errcheck = check_error_code
|
||||
_capi.fdb_future_get_key.argtypes = [ctypes.c_void_p, ctypes.POINTER(ctypes.POINTER(ctypes.c_byte)),
|
||||
ctypes.POINTER(ctypes.c_int)]
|
||||
_capi.fdb_future_get_key.restype = ctypes.c_int
|
||||
_capi.fdb_future_get_key.errcheck = check_error_code
|
||||
|
||||
_capi.fdb_future_get_cluster.argtypes = [ctypes.c_void_p, ctypes.POINTER(ctypes.c_void_p)]
|
||||
_capi.fdb_future_get_cluster.restype = ctypes.c_int
|
||||
_capi.fdb_future_get_cluster.errcheck = check_error_code
|
||||
_capi.fdb_future_get_value.argtypes = [ctypes.c_void_p, ctypes.POINTER(ctypes.c_int),
|
||||
ctypes.POINTER(ctypes.POINTER(ctypes.c_byte)), ctypes.POINTER(ctypes.c_int)]
|
||||
_capi.fdb_future_get_value.restype = ctypes.c_int
|
||||
_capi.fdb_future_get_value.errcheck = check_error_code
|
||||
|
||||
_capi.fdb_future_get_database.argtypes = [ctypes.c_void_p, ctypes.POINTER(ctypes.c_void_p)]
|
||||
_capi.fdb_future_get_database.restype = ctypes.c_int
|
||||
_capi.fdb_future_get_database.errcheck = check_error_code
|
||||
_capi.fdb_future_get_keyvalue_array.argtypes = [ctypes.c_void_p, ctypes.POINTER(
|
||||
ctypes.POINTER(KeyValueStruct)), ctypes.POINTER(ctypes.c_int), ctypes.POINTER(ctypes.c_int)]
|
||||
_capi.fdb_future_get_keyvalue_array.restype = int
|
||||
_capi.fdb_future_get_keyvalue_array.errcheck = check_error_code
|
||||
|
||||
_capi.fdb_future_get_value.argtypes = [ctypes.c_void_p, ctypes.POINTER(ctypes.c_int),
|
||||
ctypes.POINTER(ctypes.POINTER(ctypes.c_byte)), ctypes.POINTER(ctypes.c_int)]
|
||||
_capi.fdb_future_get_value.restype = ctypes.c_int
|
||||
_capi.fdb_future_get_value.errcheck = check_error_code
|
||||
_capi.fdb_future_get_string_array.argtypes = [ctypes.c_void_p, ctypes.POINTER(ctypes.POINTER(ctypes.c_char_p)), ctypes.POINTER(ctypes.c_int)]
|
||||
_capi.fdb_future_get_string_array.restype = int
|
||||
_capi.fdb_future_get_string_array.errcheck = check_error_code
|
||||
|
||||
_capi.fdb_future_get_keyvalue_array.argtypes = [ctypes.c_void_p, ctypes.POINTER(
|
||||
ctypes.POINTER(KeyValueStruct)), ctypes.POINTER(ctypes.c_int), ctypes.POINTER(ctypes.c_int)]
|
||||
_capi.fdb_future_get_keyvalue_array.restype = int
|
||||
_capi.fdb_future_get_keyvalue_array.errcheck = check_error_code
|
||||
_capi.fdb_create_database.argtypes = [ctypes.c_char_p, ctypes.POINTER(ctypes.c_void_p)]
|
||||
_capi.fdb_create_database.restype = ctypes.c_int
|
||||
_capi.fdb_create_database.errcheck = check_error_code
|
||||
|
||||
_capi.fdb_future_get_string_array.argtypes = [ctypes.c_void_p, ctypes.POINTER(ctypes.POINTER(ctypes.c_char_p)), ctypes.POINTER(ctypes.c_int)]
|
||||
_capi.fdb_future_get_string_array.restype = int
|
||||
_capi.fdb_future_get_string_array.errcheck = check_error_code
|
||||
_capi.fdb_database_destroy.argtypes = [ctypes.c_void_p]
|
||||
_capi.fdb_database_destroy.restype = None
|
||||
|
||||
_capi.fdb_create_cluster.argtypes = [ctypes.c_char_p]
|
||||
_capi.fdb_create_cluster.restype = ctypes.c_void_p
|
||||
_capi.fdb_database_create_transaction.argtypes = [ctypes.c_void_p, ctypes.POINTER(ctypes.c_void_p)]
|
||||
_capi.fdb_database_create_transaction.restype = ctypes.c_int
|
||||
_capi.fdb_database_create_transaction.errcheck = check_error_code
|
||||
|
||||
_capi.fdb_cluster_destroy.argtypes = [ctypes.c_void_p]
|
||||
_capi.fdb_cluster_destroy.restype = None
|
||||
_capi.fdb_database_set_option.argtypes = [ctypes.c_void_p, ctypes.c_int, ctypes.c_void_p, ctypes.c_int]
|
||||
_capi.fdb_database_set_option.restype = ctypes.c_int
|
||||
_capi.fdb_database_set_option.errcheck = check_error_code
|
||||
|
||||
_capi.fdb_cluster_create_database.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_int]
|
||||
_capi.fdb_cluster_create_database.restype = ctypes.c_void_p
|
||||
_capi.fdb_transaction_destroy.argtypes = [ctypes.c_void_p]
|
||||
_capi.fdb_transaction_destroy.restype = None
|
||||
|
||||
_capi.fdb_cluster_set_option.argtypes = [ctypes.c_void_p, ctypes.c_int, ctypes.c_void_p, ctypes.c_int]
|
||||
_capi.fdb_cluster_set_option.restype = ctypes.c_int
|
||||
_capi.fdb_cluster_set_option.errcheck = check_error_code
|
||||
_capi.fdb_transaction_cancel.argtypes = [ctypes.c_void_p]
|
||||
_capi.fdb_transaction_cancel.restype = None
|
||||
|
||||
_capi.fdb_database_destroy.argtypes = [ctypes.c_void_p]
|
||||
_capi.fdb_database_destroy.restype = None
|
||||
_capi.fdb_transaction_set_read_version.argtypes = [ctypes.c_void_p, ctypes.c_int64]
|
||||
_capi.fdb_transaction_set_read_version.restype = None
|
||||
|
||||
_capi.fdb_database_create_transaction.argtypes = [ctypes.c_void_p, ctypes.POINTER(ctypes.c_void_p)]
|
||||
_capi.fdb_database_create_transaction.restype = ctypes.c_int
|
||||
_capi.fdb_database_create_transaction.errcheck = check_error_code
|
||||
_capi.fdb_transaction_get_read_version.argtypes = [ctypes.c_void_p]
|
||||
_capi.fdb_transaction_get_read_version.restype = ctypes.c_void_p
|
||||
|
||||
_capi.fdb_database_set_option.argtypes = [ctypes.c_void_p, ctypes.c_int, ctypes.c_void_p, ctypes.c_int]
|
||||
_capi.fdb_database_set_option.restype = ctypes.c_int
|
||||
_capi.fdb_database_set_option.errcheck = check_error_code
|
||||
_capi.fdb_transaction_get.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_int, ctypes.c_int]
|
||||
_capi.fdb_transaction_get.restype = ctypes.c_void_p
|
||||
|
||||
_capi.fdb_transaction_destroy.argtypes = [ctypes.c_void_p]
|
||||
_capi.fdb_transaction_destroy.restype = None
|
||||
_capi.fdb_transaction_get_key.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_int]
|
||||
_capi.fdb_transaction_get_key.restype = ctypes.c_void_p
|
||||
|
||||
_capi.fdb_transaction_cancel.argtypes = [ctypes.c_void_p]
|
||||
_capi.fdb_transaction_cancel.restype = None
|
||||
_capi.fdb_transaction_get_range.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_void_p,
|
||||
ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_int,
|
||||
ctypes.c_int, ctypes.c_int]
|
||||
_capi.fdb_transaction_get_range.restype = ctypes.c_void_p
|
||||
|
||||
_capi.fdb_transaction_set_read_version.argtypes = [ctypes.c_void_p, ctypes.c_int64]
|
||||
_capi.fdb_transaction_set_read_version.restype = None
|
||||
_capi.fdb_transaction_add_conflict_range.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_int, ctypes.c_void_p, ctypes.c_int, ctypes.c_int]
|
||||
_capi.fdb_transaction_add_conflict_range.restype = ctypes.c_int
|
||||
_capi.fdb_transaction_add_conflict_range.errcheck = check_error_code
|
||||
|
||||
_capi.fdb_transaction_get_read_version.argtypes = [ctypes.c_void_p]
|
||||
_capi.fdb_transaction_get_read_version.restype = ctypes.c_void_p
|
||||
_capi.fdb_transaction_get_addresses_for_key.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_int]
|
||||
_capi.fdb_transaction_get_addresses_for_key.restype = ctypes.c_void_p
|
||||
|
||||
_capi.fdb_transaction_get.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_int, ctypes.c_int]
|
||||
_capi.fdb_transaction_get.restype = ctypes.c_void_p
|
||||
_capi.fdb_transaction_set_option.argtypes = [ctypes.c_void_p, ctypes.c_int, ctypes.c_void_p, ctypes.c_int]
|
||||
_capi.fdb_transaction_set_option.restype = ctypes.c_int
|
||||
_capi.fdb_transaction_set_option.errcheck = check_error_code
|
||||
|
||||
_capi.fdb_transaction_get_key.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_int]
|
||||
_capi.fdb_transaction_get_key.restype = ctypes.c_void_p
|
||||
_capi.fdb_transaction_atomic_op.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_int, ctypes.c_void_p, ctypes.c_int, ctypes.c_int]
|
||||
_capi.fdb_transaction_atomic_op.restype = None
|
||||
|
||||
_capi.fdb_transaction_get_range.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_void_p,
|
||||
ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_int,
|
||||
ctypes.c_int, ctypes.c_int]
|
||||
_capi.fdb_transaction_get_range.restype = ctypes.c_void_p
|
||||
_capi.fdb_transaction_set.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_int, ctypes.c_void_p, ctypes.c_int]
|
||||
_capi.fdb_transaction_set.restype = None
|
||||
|
||||
_capi.fdb_transaction_add_conflict_range.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_int, ctypes.c_void_p, ctypes.c_int, ctypes.c_int]
|
||||
_capi.fdb_transaction_add_conflict_range.restype = ctypes.c_int
|
||||
_capi.fdb_transaction_add_conflict_range.errcheck = check_error_code
|
||||
_capi.fdb_transaction_clear.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_int]
|
||||
_capi.fdb_transaction_clear.restype = None
|
||||
|
||||
_capi.fdb_transaction_get_addresses_for_key.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_int]
|
||||
_capi.fdb_transaction_get_addresses_for_key.restype = ctypes.c_void_p
|
||||
_capi.fdb_transaction_clear_range.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_int, ctypes.c_void_p, ctypes.c_int]
|
||||
_capi.fdb_transaction_clear_range.restype = None
|
||||
|
||||
_capi.fdb_transaction_set_option.argtypes = [ctypes.c_void_p, ctypes.c_int, ctypes.c_void_p, ctypes.c_int]
|
||||
_capi.fdb_transaction_set_option.restype = ctypes.c_int
|
||||
_capi.fdb_transaction_set_option.errcheck = check_error_code
|
||||
_capi.fdb_transaction_watch.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_int]
|
||||
_capi.fdb_transaction_watch.restype = ctypes.c_void_p
|
||||
|
||||
_capi.fdb_transaction_atomic_op.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_int, ctypes.c_void_p, ctypes.c_int, ctypes.c_int]
|
||||
_capi.fdb_transaction_atomic_op.restype = None
|
||||
_capi.fdb_transaction_commit.argtypes = [ctypes.c_void_p]
|
||||
_capi.fdb_transaction_commit.restype = ctypes.c_void_p
|
||||
|
||||
_capi.fdb_transaction_set.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_int, ctypes.c_void_p, ctypes.c_int]
|
||||
_capi.fdb_transaction_set.restype = None
|
||||
_capi.fdb_transaction_get_committed_version.argtypes = [ctypes.c_void_p, ctypes.POINTER(ctypes.c_int64)]
|
||||
_capi.fdb_transaction_get_committed_version.restype = ctypes.c_int
|
||||
_capi.fdb_transaction_get_committed_version.errcheck = check_error_code
|
||||
|
||||
_capi.fdb_transaction_clear.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_int]
|
||||
_capi.fdb_transaction_clear.restype = None
|
||||
_capi.fdb_transaction_get_versionstamp.argtypes = [ctypes.c_void_p]
|
||||
_capi.fdb_transaction_get_versionstamp.restype = ctypes.c_void_p
|
||||
|
||||
_capi.fdb_transaction_clear_range.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_int, ctypes.c_void_p, ctypes.c_int]
|
||||
_capi.fdb_transaction_clear_range.restype = None
|
||||
_capi.fdb_transaction_on_error.argtypes = [ctypes.c_void_p, ctypes.c_int]
|
||||
_capi.fdb_transaction_on_error.restype = ctypes.c_void_p
|
||||
|
||||
_capi.fdb_transaction_watch.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_int]
|
||||
_capi.fdb_transaction_watch.restype = ctypes.c_void_p
|
||||
|
||||
_capi.fdb_transaction_commit.argtypes = [ctypes.c_void_p]
|
||||
_capi.fdb_transaction_commit.restype = ctypes.c_void_p
|
||||
|
||||
_capi.fdb_transaction_get_committed_version.argtypes = [ctypes.c_void_p, ctypes.POINTER(ctypes.c_int64)]
|
||||
_capi.fdb_transaction_get_committed_version.restype = ctypes.c_int
|
||||
_capi.fdb_transaction_get_committed_version.errcheck = check_error_code
|
||||
|
||||
_capi.fdb_transaction_get_versionstamp.argtypes = [ctypes.c_void_p]
|
||||
_capi.fdb_transaction_get_versionstamp.restype = ctypes.c_void_p
|
||||
|
||||
_capi.fdb_transaction_on_error.argtypes = [ctypes.c_void_p, ctypes.c_int]
|
||||
_capi.fdb_transaction_on_error.restype = ctypes.c_void_p
|
||||
|
||||
_capi.fdb_transaction_reset.argtypes = [ctypes.c_void_p]
|
||||
_capi.fdb_transaction_reset.restype = None
|
||||
_capi.fdb_transaction_reset.argtypes = [ctypes.c_void_p]
|
||||
_capi.fdb_transaction_reset.restype = None
|
||||
|
||||
if hasattr(ctypes.pythonapi, 'Py_IncRef'):
|
||||
def _pin_callback(cb):
|
||||
|
@ -1660,13 +1626,12 @@ def init_v13(local_address, event_model=None):
|
|||
return init(event_model)
|
||||
|
||||
|
||||
open_clusters = {}
|
||||
open_databases = {}
|
||||
|
||||
cacheLock = threading.Lock()
|
||||
|
||||
|
||||
def open(cluster_file=None, database_name=b'DB', event_model=None):
|
||||
def open(cluster_file=None, event_model=None):
|
||||
"""Opens the given database (or the default database of the cluster indicated
|
||||
by the fdb.cluster file in a platform-specific location, if no cluster_file
|
||||
or database_name is provided). Initializes the FDB interface as required."""
|
||||
|
@ -1676,17 +1641,21 @@ def open(cluster_file=None, database_name=b'DB', event_model=None):
|
|||
init(event_model=event_model)
|
||||
|
||||
with cacheLock:
|
||||
if cluster_file not in open_clusters:
|
||||
open_clusters[cluster_file] = create_cluster(cluster_file)
|
||||
if cluster_file not in open_databases:
|
||||
open_databases[cluster_file] = create_database(cluster_file)
|
||||
|
||||
if (cluster_file, database_name) not in open_databases:
|
||||
open_databases[(cluster_file, database_name)] = open_clusters[cluster_file].open_database(database_name)
|
||||
return open_databases[(cluster_file)]
|
||||
|
||||
|
||||
return open_databases[(cluster_file, database_name)]
|
||||
def open_v609(cluster_file=None, database_name=b'DB', event_model=None):
|
||||
if database_name != b'DB':
|
||||
raise FDBError(2013) # invalid_database_name
|
||||
|
||||
return open(cluster_file, event_model)
|
||||
|
||||
|
||||
def open_v13(cluster_id_path, database_name, local_address=None, event_model=None):
|
||||
return open(cluster_id_path, database_name, event_model)
|
||||
return open_v609(cluster_id_path, database_name, event_model)
|
||||
|
||||
|
||||
import atexit
|
||||
|
|
|
@ -70,8 +70,15 @@ module FDB
|
|||
raise "FoundationDB API version error"
|
||||
end
|
||||
|
||||
FDBC.init_c_api()
|
||||
|
||||
require_relative 'fdbtuple'
|
||||
require_relative 'fdbdirectory'
|
||||
|
||||
if version < 610
|
||||
require_relative 'fdbimpl_v609'
|
||||
end
|
||||
|
||||
if version > 22
|
||||
require_relative 'fdblocality'
|
||||
end
|
||||
|
|
|
@ -64,64 +64,61 @@ module FDB
|
|||
typedef :int, :fdb_error
|
||||
typedef :int, :fdb_bool
|
||||
|
||||
attach_function :fdb_get_error, [ :fdb_error ], :string
|
||||
|
||||
attach_function :fdb_network_set_option, [ :int, :pointer, :int ], :fdb_error
|
||||
attach_function :fdb_setup_network, [ ], :fdb_error
|
||||
attach_function :fdb_run_network, [ ], :fdb_error, :blocking => true
|
||||
attach_function :fdb_stop_network, [ ], :fdb_error
|
||||
|
||||
attach_function :fdb_future_cancel, [ :pointer ], :void
|
||||
attach_function :fdb_future_release_memory, [ :pointer ], :void
|
||||
attach_function :fdb_future_destroy, [ :pointer ], :void
|
||||
attach_function :fdb_future_block_until_ready, [ :pointer ], :fdb_error, :blocking => true
|
||||
attach_function :fdb_future_is_ready, [ :pointer ], :fdb_bool
|
||||
|
||||
callback :fdb_future_callback, [ :pointer, :pointer ], :void
|
||||
attach_function :fdb_future_set_callback, [ :pointer, :fdb_future_callback, :pointer ], :fdb_error
|
||||
|
||||
attach_function :fdb_future_get_error, [ :pointer ], :fdb_error
|
||||
attach_function :fdb_future_get_version, [ :pointer, :pointer ], :fdb_error
|
||||
attach_function :fdb_future_get_key, [ :pointer, :pointer, :pointer ], :fdb_error
|
||||
attach_function :fdb_future_get_cluster, [ :pointer, :pointer ], :fdb_error
|
||||
attach_function :fdb_future_get_database, [ :pointer, :pointer ], :fdb_error
|
||||
attach_function :fdb_future_get_value, [ :pointer, :pointer, :pointer, :pointer ], :fdb_error
|
||||
attach_function :fdb_future_get_keyvalue_array, [ :pointer, :pointer, :pointer, :pointer ], :fdb_error
|
||||
attach_function :fdb_future_get_string_array, [ :pointer, :pointer, :pointer ], :fdb_error
|
||||
|
||||
attach_function :fdb_create_cluster, [ :string ], :pointer
|
||||
attach_function :fdb_cluster_destroy, [ :pointer ], :void
|
||||
attach_function :fdb_cluster_set_option, [ :pointer, :int, :pointer, :int ], :fdb_error
|
||||
|
||||
attach_function :fdb_cluster_create_database, [ :pointer, :pointer, :int ], :pointer
|
||||
attach_function :fdb_database_destroy, [ :pointer ], :void
|
||||
attach_function :fdb_database_set_option, [ :pointer, :int, :pointer, :int ], :fdb_error
|
||||
|
||||
attach_function :fdb_database_create_transaction, [ :pointer, :pointer ], :fdb_error
|
||||
attach_function :fdb_transaction_destroy, [ :pointer ], :void
|
||||
attach_function :fdb_transaction_cancel, [ :pointer ], :void
|
||||
attach_function :fdb_transaction_atomic_op, [ :pointer, :pointer, :int, :pointer, :int, :int ], :void
|
||||
attach_function :fdb_transaction_add_conflict_range, [ :pointer, :pointer, :int, :pointer, :int, :int ], :int
|
||||
attach_function :fdb_transaction_get_addresses_for_key, [ :pointer, :pointer, :int ], :pointer
|
||||
attach_function :fdb_transaction_set_option, [ :pointer, :int, :pointer, :int ], :fdb_error
|
||||
attach_function :fdb_transaction_set_read_version, [ :pointer, :int64 ], :void
|
||||
attach_function :fdb_transaction_get_read_version, [ :pointer ], :pointer
|
||||
attach_function :fdb_transaction_get, [ :pointer, :pointer, :int, :int ], :pointer
|
||||
attach_function :fdb_transaction_get_key, [ :pointer, :pointer, :int, :int, :int, :int ], :pointer
|
||||
attach_function :fdb_transaction_get_range, [ :pointer, :pointer, :int, :int, :int, :pointer, :int, :int, :int, :int, :int, :int, :int, :int, :int ], :pointer
|
||||
attach_function :fdb_transaction_set, [ :pointer, :pointer, :int, :pointer, :int ], :void
|
||||
attach_function :fdb_transaction_clear, [ :pointer, :pointer, :int ], :void
|
||||
attach_function :fdb_transaction_clear_range, [ :pointer, :pointer, :int, :pointer, :int ], :void
|
||||
attach_function :fdb_transaction_watch, [ :pointer, :pointer, :int ], :pointer
|
||||
attach_function :fdb_transaction_commit, [ :pointer ], :pointer
|
||||
attach_function :fdb_transaction_get_committed_version, [ :pointer, :pointer ], :fdb_error
|
||||
attach_function :fdb_transaction_get_versionstamp, [ :pointer ], :pointer
|
||||
attach_function :fdb_transaction_on_error, [ :pointer, :fdb_error ], :pointer
|
||||
attach_function :fdb_transaction_reset, [ :pointer ], :void
|
||||
|
||||
attach_function :fdb_select_api_version_impl, [ :int, :int ], :fdb_error
|
||||
attach_function :fdb_get_max_api_version, [ ], :int
|
||||
|
||||
def self.init_c_api
|
||||
attach_function :fdb_get_error, [ :fdb_error ], :string
|
||||
|
||||
attach_function :fdb_network_set_option, [ :int, :pointer, :int ], :fdb_error
|
||||
attach_function :fdb_setup_network, [ ], :fdb_error
|
||||
attach_function :fdb_run_network, [ ], :fdb_error, :blocking => true
|
||||
attach_function :fdb_stop_network, [ ], :fdb_error
|
||||
|
||||
attach_function :fdb_future_cancel, [ :pointer ], :void
|
||||
attach_function :fdb_future_release_memory, [ :pointer ], :void
|
||||
attach_function :fdb_future_destroy, [ :pointer ], :void
|
||||
attach_function :fdb_future_block_until_ready, [ :pointer ], :fdb_error, :blocking => true
|
||||
attach_function :fdb_future_is_ready, [ :pointer ], :fdb_bool
|
||||
|
||||
callback :fdb_future_callback, [ :pointer, :pointer ], :void
|
||||
attach_function :fdb_future_set_callback, [ :pointer, :fdb_future_callback, :pointer ], :fdb_error
|
||||
|
||||
attach_function :fdb_future_get_error, [ :pointer ], :fdb_error
|
||||
attach_function :fdb_future_get_version, [ :pointer, :pointer ], :fdb_error
|
||||
attach_function :fdb_future_get_key, [ :pointer, :pointer, :pointer ], :fdb_error
|
||||
attach_function :fdb_future_get_value, [ :pointer, :pointer, :pointer, :pointer ], :fdb_error
|
||||
attach_function :fdb_future_get_keyvalue_array, [ :pointer, :pointer, :pointer, :pointer ], :fdb_error
|
||||
attach_function :fdb_future_get_string_array, [ :pointer, :pointer, :pointer ], :fdb_error
|
||||
|
||||
attach_function :fdb_create_database, [ :string, :pointer ], :fdb_error
|
||||
|
||||
attach_function :fdb_database_destroy, [ :pointer ], :void
|
||||
attach_function :fdb_database_set_option, [ :pointer, :int, :pointer, :int ], :fdb_error
|
||||
|
||||
attach_function :fdb_database_create_transaction, [ :pointer, :pointer ], :fdb_error
|
||||
attach_function :fdb_transaction_destroy, [ :pointer ], :void
|
||||
attach_function :fdb_transaction_cancel, [ :pointer ], :void
|
||||
attach_function :fdb_transaction_atomic_op, [ :pointer, :pointer, :int, :pointer, :int, :int ], :void
|
||||
attach_function :fdb_transaction_add_conflict_range, [ :pointer, :pointer, :int, :pointer, :int, :int ], :int
|
||||
attach_function :fdb_transaction_get_addresses_for_key, [ :pointer, :pointer, :int ], :pointer
|
||||
attach_function :fdb_transaction_set_option, [ :pointer, :int, :pointer, :int ], :fdb_error
|
||||
attach_function :fdb_transaction_set_read_version, [ :pointer, :int64 ], :void
|
||||
attach_function :fdb_transaction_get_read_version, [ :pointer ], :pointer
|
||||
attach_function :fdb_transaction_get, [ :pointer, :pointer, :int, :int ], :pointer
|
||||
attach_function :fdb_transaction_get_key, [ :pointer, :pointer, :int, :int, :int, :int ], :pointer
|
||||
attach_function :fdb_transaction_get_range, [ :pointer, :pointer, :int, :int, :int, :pointer, :int, :int, :int, :int, :int, :int, :int, :int, :int ], :pointer
|
||||
attach_function :fdb_transaction_set, [ :pointer, :pointer, :int, :pointer, :int ], :void
|
||||
attach_function :fdb_transaction_clear, [ :pointer, :pointer, :int ], :void
|
||||
attach_function :fdb_transaction_clear_range, [ :pointer, :pointer, :int, :pointer, :int ], :void
|
||||
attach_function :fdb_transaction_watch, [ :pointer, :pointer, :int ], :pointer
|
||||
attach_function :fdb_transaction_commit, [ :pointer ], :pointer
|
||||
attach_function :fdb_transaction_get_committed_version, [ :pointer, :pointer ], :fdb_error
|
||||
attach_function :fdb_transaction_get_versionstamp, [ :pointer ], :pointer
|
||||
attach_function :fdb_transaction_on_error, [ :pointer, :fdb_error ], :pointer
|
||||
attach_function :fdb_transaction_reset, [ :pointer ], :void
|
||||
end
|
||||
|
||||
class KeyValueStruct < FFI::Struct
|
||||
pack 4
|
||||
layout :key, :pointer,
|
||||
|
@ -156,7 +153,7 @@ module FDB
|
|||
@@ffi_callbacks
|
||||
end
|
||||
|
||||
[ "Network", "Cluster", "Database", "Transaction" ].each do |scope|
|
||||
[ "Network", "Database", "Transaction" ].each do |scope|
|
||||
klass = FDB.const_set("#{scope}Options", Class.new)
|
||||
klass.class_eval do
|
||||
define_method(:initialize) do |setfunc|
|
||||
|
@ -242,6 +239,10 @@ module FDB
|
|||
nil
|
||||
end
|
||||
|
||||
class << self
|
||||
private :init
|
||||
end
|
||||
|
||||
def self.stop()
|
||||
FDBC.check_error FDBC.fdb_stop_network
|
||||
end
|
||||
|
@ -254,11 +255,10 @@ module FDB
|
|||
end
|
||||
end
|
||||
|
||||
@@open_clusters = {}
|
||||
@@open_databases = {}
|
||||
@@cache_lock = Mutex.new
|
||||
|
||||
def self.open( cluster_file = nil, database_name = "DB" )
|
||||
def self.open( cluster_file = nil )
|
||||
@@network_thread_monitor.synchronize do
|
||||
if ! @@network_thread
|
||||
init
|
||||
|
@ -266,15 +266,13 @@ module FDB
|
|||
end
|
||||
|
||||
@@cache_lock.synchronize do
|
||||
if ! @@open_clusters.has_key? cluster_file
|
||||
@@open_clusters[cluster_file] = create_cluster( cluster_file )
|
||||
if ! @@open_databases.has_key? [cluster_file]
|
||||
dpointer = FFI::MemoryPointer.new :pointer
|
||||
FDBC.check_error FDBC.fdb_create_database(cluster_file, dpointer)
|
||||
@@open_databases[cluster_file] = Database.new dpointer.get_pointer(0)
|
||||
end
|
||||
|
||||
if ! @@open_databases.has_key? [cluster_file, database_name]
|
||||
@@open_databases[[cluster_file, database_name]] = @@open_clusters[cluster_file].open_database(database_name)
|
||||
end
|
||||
|
||||
@@open_databases[[cluster_file, database_name]]
|
||||
@@open_databases[cluster_file]
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -503,41 +501,6 @@ module FDB
|
|||
end
|
||||
end
|
||||
|
||||
def self.create_cluster(cluster=nil)
|
||||
f = FDBC.fdb_create_cluster(cluster)
|
||||
cpointer = FFI::MemoryPointer.new :pointer
|
||||
FDBC.check_error FDBC.fdb_future_block_until_ready(f)
|
||||
FDBC.check_error FDBC.fdb_future_get_cluster(f, cpointer)
|
||||
Cluster.new cpointer.get_pointer(0)
|
||||
end
|
||||
|
||||
class Cluster < FormerFuture
|
||||
attr_reader :options
|
||||
|
||||
def self.finalize(ptr)
|
||||
proc do
|
||||
# puts "Destroying cluster #{ptr}"
|
||||
FDBC.fdb_cluster_destroy(ptr)
|
||||
end
|
||||
end
|
||||
|
||||
def initialize(cpointer)
|
||||
@cpointer = cpointer
|
||||
@options = ClusterOptions.new lambda { |code, param|
|
||||
FDBC.check_error FDBC.fdb_cluster_set_option(cpointer, code, param, param.nil? ? 0 : param.bytesize)
|
||||
}
|
||||
ObjectSpace.define_finalizer(self, self.class.finalize(@cpointer))
|
||||
end
|
||||
|
||||
def open_database(name="DB")
|
||||
f = FDBC.fdb_cluster_create_database(@cpointer, name, name.bytesize)
|
||||
dpointer = FFI::MemoryPointer.new :pointer
|
||||
FDBC.check_error FDBC.fdb_future_block_until_ready(f)
|
||||
FDBC.check_error FDBC.fdb_future_get_database(f, dpointer)
|
||||
Database.new dpointer.get_pointer(0)
|
||||
end
|
||||
end
|
||||
|
||||
class Database < FormerFuture
|
||||
attr_reader :options
|
||||
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
#encoding: BINARY
|
||||
|
||||
#
|
||||
# fdbimpl.rb
|
||||
#
|
||||
# This source file is part of the FoundationDB open source project
|
||||
#
|
||||
# Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
# FoundationDB Ruby API
|
||||
|
||||
# Documentation for this API can be found at
|
||||
# https://apple.github.io/foundationdb/api-ruby.html
|
||||
|
||||
module FDB
|
||||
class << self
|
||||
alias_method :open_impl, :open
|
||||
def open( cluster_file = nil, database_name = "DB" )
|
||||
if database_name != "DB"
|
||||
raise Error.new(2013) # invalid_database_name
|
||||
end
|
||||
|
||||
open_impl(cluster_file)
|
||||
end
|
||||
|
||||
def create_cluster(cluster_file_path=nil)
|
||||
Cluster.new cluster_file_path
|
||||
end
|
||||
|
||||
public :init
|
||||
end
|
||||
|
||||
class ClusterOptions
|
||||
end
|
||||
|
||||
class Cluster < FormerFuture
|
||||
attr_reader :options
|
||||
|
||||
def initialize(cluster_file_path)
|
||||
@cluster_file_path = cluster_file_path
|
||||
@options = ClusterOptions.new
|
||||
end
|
||||
|
||||
def open_database(name="DB")
|
||||
FDB.open(@cluster_file_path, name)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
|
@ -85,7 +85,7 @@ Specifying the cluster file
|
|||
All FoundationDB components can be configured to use a specified cluster file:
|
||||
|
||||
* The ``fdbcli`` tool allows a cluster file to be passed on the command line using the ``-C`` option.
|
||||
* The :doc:`client APIs <api-reference>` allow a cluster file to be passed when connecting to a cluster, usually via ``open()`` or ``create_cluster()``.
|
||||
* The :doc:`client APIs <api-reference>` allow a cluster file to be passed when connecting to a cluster, usually via ``open()``.
|
||||
* A FoundationDB server or ``backup-agent`` allow a cluster file to be specified in :ref:`foundationdb.conf <foundationdb-conf>`.
|
||||
|
||||
In addition, FoundationDB allows you to use the environment variable ``FDB_CLUSTER_FILE`` to specify a cluster file. This approach is helpful if you operate or access more than one cluster.
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
.. |reset-func-name| replace:: :func:`reset <fdb_transaction_reset()>`
|
||||
.. |reset-func| replace:: :func:`fdb_transaction_reset()`
|
||||
.. |cancel-func| replace:: :func:`fdb_transaction_cancel()`
|
||||
.. |init-func| replace:: FIXME
|
||||
.. |open-func| replace:: FIXME
|
||||
.. |set-cluster-file-func| replace:: FIXME
|
||||
.. |set-local-address-func| replace:: FIXME
|
||||
|
@ -292,22 +291,6 @@ See :ref:`developer-guide-programming-with-futures` for further (language-indepe
|
|||
|
||||
|future-memory-mine|
|
||||
|
||||
.. function:: fdb_error_t fdb_future_get_cluster(FDBFuture* future, FDBCluster** out_cluster)
|
||||
|
||||
Extracts a value of type :type:`FDBCluster*` from an :type:`FDBFuture` into a caller-provided variable. |future-warning|
|
||||
|
||||
|future-get-return1| |future-get-return2|.
|
||||
|
||||
|future-memory-yours1| :type:`FDBCluster` |future-memory-yours2| :func:`fdb_cluster_destroy()` |future-memory-yours3|
|
||||
|
||||
.. function:: fdb_error_t fdb_future_get_database(FDBFuture* future, FDBDatabase** out_database)
|
||||
|
||||
Extracts a value of type :type:`FDBDatabase*` from an :type:`FDBFuture` into a caller-provided variable. |future-warning|
|
||||
|
||||
|future-get-return1| |future-get-return2|.
|
||||
|
||||
|future-memory-yours1| :type:`FDBDatabase` |future-memory-yours2| ``fdb_database_destroy(*out_database)`` |future-memory-yours3|
|
||||
|
||||
.. function:: fdb_error_t fdb_future_get_value(FDBFuture* future, fdb_bool_t* out_present, uint8_t const** out_value, int* out_value_length)
|
||||
|
||||
Extracts a database value from an :type:`FDBFuture` into caller-provided variables. |future-warning|
|
||||
|
@ -379,42 +362,6 @@ See :ref:`developer-guide-programming-with-futures` for further (language-indepe
|
|||
:data:`value_length`
|
||||
The length of the value pointed to by :data:`value`.
|
||||
|
||||
Cluster
|
||||
=======
|
||||
|
||||
.. type:: FDBCluster
|
||||
|
||||
An opaque type that represents a Cluster in the FoundationDB C API.
|
||||
|
||||
.. function:: FDBFuture* fdb_create_cluster(const char* cluster_file_path)
|
||||
|
||||
|future-return0| an :type:`FDBCluster` object. |future-return1| call :func:`fdb_future_get_cluster()` to extract the :type:`FDBCluster` object, |future-return2|
|
||||
|
||||
:data:`cluster_file_path`
|
||||
A NULL-terminated string giving a local path of a :ref:`cluster file <foundationdb-cluster-file>` (often called 'fdb.cluster') which contains connection information for the FoundationDB cluster. If cluster_file_path is NULL or an empty string, then a :ref:`default cluster file <default-cluster-file>` will be used.
|
||||
|
||||
.. function:: void fdb_cluster_destroy(FDBCluster* cluster)
|
||||
|
||||
Destroys an :type:`FDBCluster` object. It must be called exactly once for each successful call to :func:`fdb_future_get_cluster()`. This function only destroys a handle to the cluster -- your cluster will be fine!
|
||||
|
||||
.. function:: fdb_error_t fdb_cluster_set_option(FDBCluster* cluster, FDBClusterOption option, uint8_t const* value, int value_length)
|
||||
|
||||
Called to set an option on an :type:`FDBCluster`. |option-parameter| :func:`fdb_cluster_set_option()` returns.
|
||||
|
||||
.. type:: FDBClusterOption
|
||||
|
||||
|option-doc|
|
||||
|
||||
.. function:: FDBFuture* fdb_cluster_create_database(FDBCluster *cluster, uint8_t const* db_name, int db_name_length)
|
||||
|
||||
|future-return0| an :type:`FDBDatabase` object. |future-return1| call :func:`fdb_future_get_database()` to extract the :type:`FDBDatabase` object, |future-return2|
|
||||
|
||||
:data:`db_name`
|
||||
A pointer to the name of the database to be opened. |no-null| In the current FoundationDB API, the database name *must* be "DB".
|
||||
|
||||
:data:`db_name_length`
|
||||
|length-of| :data:`db_name`.
|
||||
|
||||
Database
|
||||
========
|
||||
|
||||
|
@ -424,9 +371,19 @@ An |database-blurb1| Modifications to a database are performed via transactions.
|
|||
|
||||
An opaque type that represents a database in the FoundationDB C API.
|
||||
|
||||
.. function:: fdb_error_t fdb_create_database(const char* cluster_file_path, FDBDatabase** out_database)
|
||||
|
||||
Creates a new database connected the specified cluster. The caller assumes ownership of the :type:`FDBDatabase` object and must destroy it with :func:`fdb_database_destroy()`.
|
||||
|
||||
:data:`cluster_file_path`
|
||||
A NULL-terminated string giving a local path of a :ref:`cluster file <foundationdb-cluster-file>` (often called 'fdb.cluster') which contains connection information for the FoundationDB cluster. If cluster_file_path is NULL or an empty string, then a :ref:`default cluster file <default-cluster-file>` will be used.
|
||||
|
||||
:data:`*out_database`
|
||||
Set to point to the newly created :type:`FDBDatabase`.
|
||||
|
||||
.. function:: void fdb_database_destroy(FDBDatabase* database)
|
||||
|
||||
Destroys an :type:`FDBDatabase` object. It must be called exactly once for each successful call to :func:`fdb_future_get_database()`. This function only destroys a handle to the database -- your database will be fine!
|
||||
Destroys an :type:`FDBDatabase` object. It must be called exactly once for each successful call to :func:`fdb_create_database()`. This function only destroys a handle to the database -- your database will be fine!
|
||||
|
||||
.. function:: fdb_error_t fdb_database_set_option(FDBDatabase* database, FDBDatabaseOption option, uint8_t const* value, int value_length)
|
||||
|
||||
|
|
|
@ -234,7 +234,7 @@
|
|||
|
||||
.. |network-options-warning| replace::
|
||||
|
||||
It is an error to set these options after the first call to |open-func| or |init-func| anywhere in your application.
|
||||
It is an error to set these options after the first call to |open-func| anywhere in your application.
|
||||
|
||||
.. |tls-options-burb| replace::
|
||||
|
||||
|
@ -398,7 +398,7 @@
|
|||
Cancels |future-type-string| and its associated asynchronous operation. If called before the future is ready, attempts to access its value will |error-raise-type| an :ref:`operation_cancelled <developer-guide-error-codes>` |error-type|. Cancelling a future which is already ready has no effect. Note that even if a future is not ready, its associated asynchronous operation may have succesfully completed and be unable to be cancelled.
|
||||
|
||||
.. |fdb-open-blurb| replace::
|
||||
Initializes the FoundationDB API, connects to the cluster specified by the :ref:`cluster file <foundationdb-cluster-file>`, and opens the database with the specified name. This function is often called without any parameters, using only the defaults. If no cluster file is passed, FoundationDB automatically :ref:`determines a cluster file <specifying-a-cluster-file>` with which to connect to a cluster.
|
||||
Initializes the FoundationDB API and connects to the cluster specified by the :ref:`cluster file <foundationdb-cluster-file>`. This function is often called without any parameters, using only the defaults. If no cluster file is passed, FoundationDB automatically :ref:`determines a cluster file <specifying-a-cluster-file>` with which to connect to a cluster.
|
||||
|
||||
.. |fdb-transactional-unknown-result-note| replace::
|
||||
In some failure scenarios, it is possible that your transaction will be executed twice. See :ref:`developer-guide-unknown-results` for more information.
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
.. |reset-func-name| replace:: :func:`reset <Transaction.reset>`
|
||||
.. |reset-func| replace:: :func:`Transaction.reset`
|
||||
.. |cancel-func| replace:: :func:`Transaction.cancel`
|
||||
.. |init-func| replace:: :func:`fdb.init`
|
||||
.. |open-func| replace:: :func:`fdb.open`
|
||||
.. |on-error-func| replace:: :meth:`Transaction.on_error`
|
||||
.. |null-type| replace:: ``None``
|
||||
|
@ -86,33 +85,18 @@ For API changes between version 13 and |api-version| (for the purpose of porting
|
|||
Opening a database
|
||||
==================
|
||||
|
||||
After importing the ``fdb`` module and selecting an API version, you probably want to open a :class:`Database`. The simplest way of doing this is using :func:`open`::
|
||||
After importing the ``fdb`` module and selecting an API version, you probably want to open a :class:`Database` using :func:`open`::
|
||||
|
||||
import fdb
|
||||
fdb.api_version(610)
|
||||
db = fdb.open()
|
||||
|
||||
.. function:: open( cluster_file=None, db_name="DB", event_model=None )
|
||||
.. function:: open( cluster_file=None, event_model=None )
|
||||
|
||||
|fdb-open-blurb|
|
||||
|
||||
.. param event_model:: Can be used to select alternate :ref:`api-python-event-models`
|
||||
|
||||
.. note:: In this release, db_name must be "DB".
|
||||
|
||||
.. note:: ``fdb.open()`` combines the effect of :func:`init`, :func:`create_cluster`, and :meth:`Cluster.open_database`.
|
||||
|
||||
.. function:: init()
|
||||
|
||||
Initializes the FoundationDB API, creating a thread for the FoundationDB client and initializing the client's networking engine. :func:`init()` can only be called once. If called subsequently or after :func:`open`, it will raise an ``client_invalid_operation`` error.
|
||||
|
||||
.. function:: create_cluster( cluster_file=None )
|
||||
|
||||
Connects to the cluster specified by :ref:`cluster_file <foundationdb-cluster-file>`, or by a :ref:`default cluster file <default-cluster-file>` if
|
||||
``cluster_file`` is None. :func:`init` must be called first.
|
||||
|
||||
Returns a |future-type| :class:`Cluster` object.
|
||||
|
||||
.. data:: options
|
||||
|
||||
|network-options-blurb|
|
||||
|
@ -175,19 +159,6 @@ After importing the ``fdb`` module and selecting an API version, you probably wa
|
|||
|
||||
|option-tls-key-bytes|
|
||||
|
||||
Cluster objects
|
||||
===============
|
||||
|
||||
.. class:: Cluster
|
||||
|
||||
.. method:: Cluster.open_database(name="DB")
|
||||
|
||||
Opens a database with the given name.
|
||||
|
||||
Returns a |future-type| :class:`Database` object.
|
||||
|
||||
.. note:: In this release, name **must** be "DB".
|
||||
|
||||
.. _api-python-keys:
|
||||
|
||||
Keys and values
|
||||
|
@ -966,7 +937,7 @@ The following streaming modes are available:
|
|||
Event models
|
||||
============
|
||||
|
||||
By default, the FoundationDB Python API assumes that the calling program uses threads (as provided by the ``threading`` module) for concurrency. This means that blocking operations will block the current Python thread. This behavior can be changed by specifying the optional ``event_model`` parameter to the :func:`open` or :func:`init` functions.
|
||||
By default, the FoundationDB Python API assumes that the calling program uses threads (as provided by the ``threading`` module) for concurrency. This means that blocking operations will block the current Python thread. This behavior can be changed by specifying the optional ``event_model`` parameter to the :func:`open` function.
|
||||
|
||||
The following event models are available:
|
||||
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
.. |reset-func-name| replace:: :meth:`reset <Transaction.reset>`
|
||||
.. |reset-func| replace:: :meth:`Transaction.reset`
|
||||
.. |cancel-func| replace:: :meth:`Transaction.cancel`
|
||||
.. |init-func| replace:: :func:`FDB.init`
|
||||
.. |open-func| replace:: :func:`FDB.open`
|
||||
.. |on-error-func| replace:: :meth:`Transaction.on_error`
|
||||
.. |null-type| replace:: ``nil``
|
||||
|
@ -75,28 +74,16 @@ For API changes between version 14 and |api-version| (for the purpose of porting
|
|||
Opening a database
|
||||
==================
|
||||
|
||||
After requiring the ``FDB`` gem and selecting an API version, you probably want to open a :class:`Database`. The simplest way of doing this is using :func:`open`::
|
||||
After requiring the ``FDB`` gem and selecting an API version, you probably want to open a :class:`Database` using :func:`open`::
|
||||
|
||||
require 'fdb'
|
||||
FDB.api_version 610
|
||||
db = FDB.open
|
||||
|
||||
.. function:: open( cluster_file=nil, db_name="DB" ) -> Database
|
||||
.. function:: open( cluster_file=nil ) -> Database
|
||||
|
||||
|fdb-open-blurb|
|
||||
|
||||
.. note:: In this release, db_name must be "DB".
|
||||
|
||||
.. note:: ``fdb.open`` combines the effect of :func:`init`, :func:`create_cluster`, and :meth:`Cluster.open_database`.
|
||||
|
||||
.. function:: init() -> nil
|
||||
|
||||
Initializes the FoundationDB API, creating a thread for the FoundationDB client and initializing the client's networking engine. :func:`init` can only be called once. If called subsequently or after :func:`open`, it will raise a ``client_invalid_operation`` error.
|
||||
|
||||
.. function:: create_cluster(cluster_file=nil) -> Cluster
|
||||
|
||||
Connects to the cluster specified by :ref:`cluster_file <foundationdb-cluster-file>`, or by a :ref:`default cluster file <default-cluster-file>` if ``cluster_file`` is ``nil``.
|
||||
|
||||
.. global:: FDB.options
|
||||
|
||||
|network-options-blurb|
|
||||
|
@ -160,17 +147,6 @@ After requiring the ``FDB`` gem and selecting an API version, you probably want
|
|||
.. method :: FDB.options.set_disable_multi_version_client_api() -> nil
|
||||
|
||||
|
||||
Cluster objects
|
||||
===============
|
||||
|
||||
.. class:: Cluster
|
||||
|
||||
.. method:: Cluster.open_database(name="DB") -> Database
|
||||
|
||||
Opens a database with the given name.
|
||||
|
||||
.. note:: In this release, name **must** be "DB".
|
||||
|
||||
.. _api-ruby-keys:
|
||||
|
||||
Keys and values
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
.. |get-key-func| replace:: get_key()
|
||||
.. |get-range-func| replace:: get_range()
|
||||
.. |commit-func| replace:: FIXME
|
||||
.. |init-func| replace:: FIXME
|
||||
.. |open-func| replace:: FIXME
|
||||
.. |set-cluster-file-func| replace:: FIXME
|
||||
.. |set-local-address-func| replace:: FIXME
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
.. |get-key-func| replace:: get_key()
|
||||
.. |get-range-func| replace:: get_range()
|
||||
.. |commit-func| replace:: ``commit()``
|
||||
.. |init-func| replace:: FIXME
|
||||
.. |open-func| replace:: FIXME
|
||||
.. |set-cluster-file-func| replace:: FIXME
|
||||
.. |set-local-address-func| replace:: FIXME
|
||||
|
|
|
@ -20,6 +20,16 @@ Status
|
|||
Bindings
|
||||
--------
|
||||
|
||||
* The API to create a database has been simplified across the bindings. All changes are backward compatible with previous API versions, with one exception in Java noted below.
|
||||
* C: `FDBCluster` objects and related methods (`fdb_create_cluster`, `fdb_cluster_create_database`, `fdb_cluster_set_option`, `fdb_cluster_destroy`, `fdb_future_get_cluster`) have been removed.
|
||||
* C: Added `fdb_create_database` that creates a new `FDBDatabase` object synchronously and removed `fdb_future_get_database`.
|
||||
* Python: Removed `fdb.init`, `fdb.create_cluster`, and `fdb.Cluster`. `fdb.open` no longer accepts a `database_name` parameter.
|
||||
* Java: Deprecated `FDB.createCluster` and `Cluster`. The preferred way to get a `Database` is by using `FDB.open`, which should work in both new and old API versions.
|
||||
* Java: Removed `Cluster(long cPtr, Executor executor)` constructor. This is API breaking for any code that has subclassed the `Cluster` class and is not protected by API versioning.
|
||||
* Ruby: Removed `FDB.init`, `FDB.create_cluster`, and `FDB.Cluster`. `FDB.open` no longer accepts a `database_name` parameter.
|
||||
* Golang: Deprecated `fdb.StartNetwork`, `fdb.Open`, `fdb.MustOpen`, and `fdb.CreateCluster` and added `fdb.OpenDatabase` and `fdb.MustOpenDatabase`. The preferred way to start the network and get a `Database` is by using `FDB.OpenDatabase` or `FDB.OpenDefault`.
|
||||
* Flow: Deprecated `API::createCluster` and `Cluster` and added `API::createDatabase`. The preferred way to get a `Database` is by using `API::createDatabase`.
|
||||
|
||||
Other Changes
|
||||
-------------
|
||||
|
||||
|
|
|
@ -75,8 +75,12 @@ public:
|
|||
Error deferredError;
|
||||
bool lockAware;
|
||||
|
||||
bool isError() {
|
||||
return deferredError.code() != invalid_error_code;
|
||||
}
|
||||
|
||||
void checkDeferredError() {
|
||||
if( deferredError.code() != invalid_error_code ) {
|
||||
if(isError()) {
|
||||
throw deferredError;
|
||||
}
|
||||
}
|
||||
|
@ -91,6 +95,8 @@ public:
|
|||
Future<Void> clientInfoMonitor, Standalone<StringRef> dbId, int taskID, LocalityData const& clientLocality,
|
||||
bool enableLocalityLoadBalance, bool lockAware, int apiVersion = Database::API_VERSION_LATEST );
|
||||
|
||||
explicit DatabaseContext( const Error &err );
|
||||
|
||||
// Key DB-specific information
|
||||
AsyncTrigger masterProxiesChangeTrigger;
|
||||
Future<Void> monitorMasterProxiesInfoChange;
|
||||
|
|
|
@ -94,7 +94,7 @@ public:
|
|||
virtual void runNetwork() = 0;
|
||||
virtual void stopNetwork() = 0;
|
||||
|
||||
virtual ThreadFuture<Reference<IDatabase>> createDatabase(const char *clusterFilePath) = 0;
|
||||
virtual Reference<IDatabase> createDatabase(const char *clusterFilePath) = 0;
|
||||
|
||||
virtual void addNetworkThreadCompletionHook(void (*hook)(void*), void *hookParameter) = 0;
|
||||
};
|
||||
|
|
|
@ -212,6 +212,21 @@ void DLTransaction::reset() {
|
|||
}
|
||||
|
||||
// DLDatabase
|
||||
DLDatabase::DLDatabase(Reference<FdbCApi> api, ThreadFuture<FdbCApi::FDBDatabase*> dbFuture) : api(api), db(nullptr) {
|
||||
ready = mapThreadFuture<FdbCApi::FDBDatabase*, Void>(dbFuture, [this](ErrorOr<FdbCApi::FDBDatabase*> db){
|
||||
if(db.isError()) {
|
||||
return ErrorOr<Void>(db.getError());
|
||||
}
|
||||
|
||||
this->db = db.get();
|
||||
return ErrorOr<Void>(Void());
|
||||
});
|
||||
}
|
||||
|
||||
ThreadFuture<Void> DLDatabase::onReady() {
|
||||
return ready;
|
||||
}
|
||||
|
||||
Reference<ITransaction> DLDatabase::createTransaction() {
|
||||
FdbCApi::FDBTransaction *tr;
|
||||
api->databaseCreateTransaction(db, &tr);
|
||||
|
@ -251,11 +266,7 @@ void DLApi::init() {
|
|||
loadClientFunction(&api->setupNetwork, lib, fdbCPath, "fdb_setup_network");
|
||||
loadClientFunction(&api->runNetwork, lib, fdbCPath, "fdb_run_network");
|
||||
loadClientFunction(&api->stopNetwork, lib, fdbCPath, "fdb_stop_network");
|
||||
loadClientFunction(&api->createCluster, lib, fdbCPath, "fdb_create_cluster");
|
||||
|
||||
loadClientFunction(&api->clusterCreateDatabase, lib, fdbCPath, "fdb_cluster_create_database");
|
||||
loadClientFunction(&api->clusterSetOption, lib, fdbCPath, "fdb_cluster_set_option");
|
||||
loadClientFunction(&api->clusterDestroy, lib, fdbCPath, "fdb_cluster_destroy");
|
||||
loadClientFunction(&api->createDatabase, lib, fdbCPath, "fdb_create_database", headerVersion >= 610);
|
||||
|
||||
loadClientFunction(&api->databaseCreateTransaction, lib, fdbCPath, "fdb_database_create_transaction");
|
||||
loadClientFunction(&api->databaseSetOption, lib, fdbCPath, "fdb_database_set_option");
|
||||
|
@ -282,7 +293,6 @@ void DLApi::init() {
|
|||
loadClientFunction(&api->transactionCancel, lib, fdbCPath, "fdb_transaction_cancel");
|
||||
loadClientFunction(&api->transactionAddConflictRange, lib, fdbCPath, "fdb_transaction_add_conflict_range");
|
||||
|
||||
loadClientFunction(&api->futureGetCluster, lib, fdbCPath, "fdb_future_get_cluster");
|
||||
loadClientFunction(&api->futureGetDatabase, lib, fdbCPath, "fdb_future_get_database");
|
||||
loadClientFunction(&api->futureGetVersion, lib, fdbCPath, "fdb_future_get_version");
|
||||
loadClientFunction(&api->futureGetError, lib, fdbCPath, "fdb_future_get_error");
|
||||
|
@ -293,6 +303,11 @@ void DLApi::init() {
|
|||
loadClientFunction(&api->futureSetCallback, lib, fdbCPath, "fdb_future_set_callback");
|
||||
loadClientFunction(&api->futureCancel, lib, fdbCPath, "fdb_future_cancel");
|
||||
loadClientFunction(&api->futureDestroy, lib, fdbCPath, "fdb_future_destroy");
|
||||
|
||||
loadClientFunction(&api->createCluster, lib, fdbCPath, "fdb_create_cluster", headerVersion < 610);
|
||||
loadClientFunction(&api->clusterCreateDatabase, lib, fdbCPath, "fdb_cluster_create_database", headerVersion < 610);
|
||||
loadClientFunction(&api->clusterDestroy, lib, fdbCPath, "fdb_cluster_destroy", headerVersion < 610);
|
||||
loadClientFunction(&api->futureGetCluster, lib, fdbCPath, "fdb_future_get_cluster", headerVersion < 610);
|
||||
}
|
||||
|
||||
void DLApi::selectApiVersion(int apiVersion) {
|
||||
|
@ -346,7 +361,7 @@ void DLApi::stopNetwork() {
|
|||
}
|
||||
}
|
||||
|
||||
ThreadFuture<Reference<IDatabase>> DLApi::createDatabase(const char *clusterFilePath) {
|
||||
Reference<IDatabase> DLApi::createDatabase609(const char *clusterFilePath) {
|
||||
FdbCApi::FDBFuture *f = api->createCluster(clusterFilePath);
|
||||
|
||||
auto clusterFuture = toThreadFuture<FdbCApi::FDBCluster*>(api, f, [](FdbCApi::FDBFuture *f, FdbCApi *api) {
|
||||
|
@ -356,22 +371,35 @@ ThreadFuture<Reference<IDatabase>> DLApi::createDatabase(const char *clusterFile
|
|||
});
|
||||
|
||||
Reference<FdbCApi> innerApi = api;
|
||||
return flatMapThreadFuture<FdbCApi::FDBCluster*, Reference<IDatabase>>(clusterFuture, [innerApi](ErrorOr<FdbCApi::FDBCluster*> cluster) {
|
||||
auto dbFuture = flatMapThreadFuture<FdbCApi::FDBCluster*, FdbCApi::FDBDatabase*>(clusterFuture, [innerApi](ErrorOr<FdbCApi::FDBCluster*> cluster) {
|
||||
if(cluster.isError()) {
|
||||
return ErrorOr<ThreadFuture<Reference<IDatabase>>>(cluster.getError());
|
||||
return ErrorOr<ThreadFuture<FdbCApi::FDBDatabase*>>(cluster.getError());
|
||||
}
|
||||
|
||||
auto dbFuture = toThreadFuture<Reference<IDatabase>>(innerApi, innerApi->clusterCreateDatabase(cluster.get(), (uint8_t*)"DB", 2), [](FdbCApi::FDBFuture *f, FdbCApi *api) {
|
||||
auto innerDbFuture = toThreadFuture<FdbCApi::FDBDatabase*>(innerApi, innerApi->clusterCreateDatabase(cluster.get(), (uint8_t*)"DB", 2), [](FdbCApi::FDBFuture *f, FdbCApi *api) {
|
||||
FdbCApi::FDBDatabase *db;
|
||||
api->futureGetDatabase(f, &db);
|
||||
return Reference<IDatabase>(new DLDatabase(Reference<FdbCApi>::addRef(api), db));
|
||||
return db;
|
||||
});
|
||||
|
||||
return ErrorOr<ThreadFuture<Reference<IDatabase>>>(mapThreadFuture<Reference<IDatabase>, Reference<IDatabase>>(dbFuture, [cluster, innerApi](ErrorOr<Reference<IDatabase>> db) {
|
||||
return ErrorOr<ThreadFuture<FdbCApi::FDBDatabase*>>(mapThreadFuture<FdbCApi::FDBDatabase*, FdbCApi::FDBDatabase*>(innerDbFuture, [cluster, innerApi](ErrorOr<FdbCApi::FDBDatabase*> db) {
|
||||
innerApi->clusterDestroy(cluster.get());
|
||||
return db;
|
||||
}));
|
||||
});
|
||||
|
||||
return Reference<DLDatabase>(new DLDatabase(api, dbFuture));
|
||||
}
|
||||
|
||||
Reference<IDatabase> DLApi::createDatabase(const char *clusterFilePath) {
|
||||
if(headerVersion >= 610) {
|
||||
FdbCApi::FDBDatabase *db;
|
||||
api->createDatabase(clusterFilePath, &db);
|
||||
return Reference<IDatabase>(new DLDatabase(api, db));
|
||||
}
|
||||
else {
|
||||
return DLApi::createDatabase609(clusterFilePath);
|
||||
}
|
||||
}
|
||||
|
||||
void DLApi::addNetworkThreadCompletionHook(void (*hook)(void*), void *hookParameter) {
|
||||
|
@ -634,28 +662,32 @@ void MultiVersionDatabase::Connector::connect() {
|
|||
connectionFuture.cancel();
|
||||
}
|
||||
|
||||
ThreadFuture<Reference<IDatabase>> dbFuture = client->api->createDatabase(clusterFilePath.c_str());
|
||||
connectionFuture = flatMapThreadFuture<Reference<IDatabase>, Void>(dbFuture, [this](ErrorOr<Reference<IDatabase>> db) {
|
||||
if(db.isError()) {
|
||||
return ErrorOr<ThreadFuture<Void>>(db.getError());
|
||||
}
|
||||
else {
|
||||
candidateDatabase = db.get();
|
||||
tr = db.get()->createTransaction();
|
||||
auto versionFuture = mapThreadFuture<Version, Void>(tr->getReadVersion(), [this](ErrorOr<Version> v) {
|
||||
// If the version attempt returns an error, we regard that as a connection (except operation_cancelled)
|
||||
if(v.isError() && v.getError().code() == error_code_operation_cancelled) {
|
||||
return ErrorOr<Void>(v.getError());
|
||||
}
|
||||
else {
|
||||
return ErrorOr<Void>(Void());
|
||||
}
|
||||
});
|
||||
candidateDatabase = client->api->createDatabase(clusterFilePath.c_str());
|
||||
if(client->external) {
|
||||
connectionFuture = candidateDatabase.castTo<DLDatabase>()->onReady();
|
||||
}
|
||||
else {
|
||||
connectionFuture = ThreadFuture<Void>(Void());
|
||||
}
|
||||
|
||||
return ErrorOr<ThreadFuture<Void>>(versionFuture);
|
||||
connectionFuture = flatMapThreadFuture<Void, Void>(connectionFuture, [this](ErrorOr<Void> ready) {
|
||||
if(ready.isError()) {
|
||||
return ErrorOr<ThreadFuture<Void>>(ready.getError());
|
||||
}
|
||||
|
||||
tr = candidateDatabase->createTransaction();
|
||||
return ErrorOr<ThreadFuture<Void>>(mapThreadFuture<Version, Void>(tr->getReadVersion(), [this](ErrorOr<Version> v) {
|
||||
// If the version attempt returns an error, we regard that as a connection (except operation_cancelled)
|
||||
if(v.isError() && v.getError().code() == error_code_operation_cancelled) {
|
||||
return ErrorOr<Void>(v.getError());
|
||||
}
|
||||
else {
|
||||
return ErrorOr<Void>(Void());
|
||||
}
|
||||
}));
|
||||
});
|
||||
|
||||
|
||||
int userParam;
|
||||
connectionFuture.callOrSetAsCallback(this, userParam, 0);
|
||||
}
|
||||
|
@ -1113,11 +1145,11 @@ void MultiVersionApi::addNetworkThreadCompletionHook(void (*hook)(void*), void *
|
|||
}
|
||||
}
|
||||
|
||||
ThreadFuture<Reference<IDatabase>> MultiVersionApi::createDatabase(const char *clusterFilePath) {
|
||||
Reference<IDatabase> MultiVersionApi::createDatabase(const char *clusterFilePath) {
|
||||
lock.enter();
|
||||
if(!networkSetup) {
|
||||
lock.leave();
|
||||
return network_not_setup();
|
||||
throw network_not_setup();
|
||||
}
|
||||
lock.leave();
|
||||
|
||||
|
@ -1126,21 +1158,15 @@ ThreadFuture<Reference<IDatabase>> MultiVersionApi::createDatabase(const char *c
|
|||
return Reference<IDatabase>(new MultiVersionDatabase(this, clusterFile, Reference<IDatabase>()));
|
||||
}
|
||||
|
||||
auto databaseFuture = localClient->api->createDatabase(clusterFilePath);
|
||||
auto db = localClient->api->createDatabase(clusterFilePath);
|
||||
if(bypassMultiClientApi) {
|
||||
return databaseFuture;
|
||||
return db;
|
||||
}
|
||||
else {
|
||||
for(auto it : externalClients) {
|
||||
TraceEvent("CreatingDatabaseOnExternalClient").detail("LibraryPath", it.second->libPath).detail("Failed", it.second->failed);
|
||||
}
|
||||
return mapThreadFuture<Reference<IDatabase>, Reference<IDatabase>>(databaseFuture, [this, clusterFile](ErrorOr<Reference<IDatabase>> database) {
|
||||
if(database.isError()) {
|
||||
return database;
|
||||
}
|
||||
|
||||
return ErrorOr<Reference<IDatabase>>(Reference<IDatabase>(new MultiVersionDatabase(this, clusterFile, database.get())));
|
||||
});
|
||||
return Reference<IDatabase>(new MultiVersionDatabase(this, clusterFile, db));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -55,12 +55,7 @@ struct FdbCApi : public ThreadSafeReferenceCounted<FdbCApi> {
|
|||
fdb_error_t (*setupNetwork)();
|
||||
fdb_error_t (*runNetwork)();
|
||||
fdb_error_t (*stopNetwork)();
|
||||
FDBFuture* (*createCluster)(const char *clusterFilePath);
|
||||
|
||||
//Cluster
|
||||
FDBFuture* (*clusterCreateDatabase)(FDBCluster *cluster, uint8_t *dbName, int dbNameLength);
|
||||
fdb_error_t (*clusterSetOption)(FDBCluster *cluster, FDBClusterOptions::Option option, uint8_t const *value, int valueLength);
|
||||
void (*clusterDestroy)(FDBCluster *cluster);
|
||||
fdb_error_t* (*createDatabase)(const char *clusterFilePath, FDBDatabase **db);
|
||||
|
||||
//Database
|
||||
fdb_error_t (*databaseCreateTransaction)(FDBDatabase *database, FDBTransaction **tr);
|
||||
|
@ -98,7 +93,6 @@ struct FdbCApi : public ThreadSafeReferenceCounted<FdbCApi> {
|
|||
uint8_t const *endKeyName, int endKeyNameLength, FDBConflictRangeTypes::Option);
|
||||
|
||||
//Future
|
||||
fdb_error_t (*futureGetCluster)(FDBFuture *f, FDBCluster **outCluster);
|
||||
fdb_error_t (*futureGetDatabase)(FDBFuture *f, FDBDatabase **outDb);
|
||||
fdb_error_t (*futureGetVersion)(FDBFuture *f, int64_t *outVersion);
|
||||
fdb_error_t (*futureGetError)(FDBFuture *f);
|
||||
|
@ -109,6 +103,12 @@ struct FdbCApi : public ThreadSafeReferenceCounted<FdbCApi> {
|
|||
fdb_error_t (*futureSetCallback)(FDBFuture *f, FDBCallback callback, void *callback_parameter);
|
||||
void (*futureCancel)(FDBFuture *f);
|
||||
void (*futureDestroy)(FDBFuture *f);
|
||||
|
||||
//Legacy Support
|
||||
FDBFuture* (*createCluster)(const char *clusterFilePath);
|
||||
FDBFuture* (*clusterCreateDatabase)(FDBCluster *cluster, uint8_t *dbName, int dbNameLength);
|
||||
void (*clusterDestroy)(FDBCluster *cluster);
|
||||
fdb_error_t (*futureGetCluster)(FDBFuture *f, FDBCluster **outCluster);
|
||||
};
|
||||
|
||||
class DLTransaction : public ITransaction, ThreadSafeReferenceCounted<DLTransaction> {
|
||||
|
@ -159,9 +159,12 @@ private:
|
|||
|
||||
class DLDatabase : public IDatabase, ThreadSafeReferenceCounted<DLDatabase> {
|
||||
public:
|
||||
DLDatabase(Reference<FdbCApi> api, FdbCApi::FDBDatabase *db) : api(api), db(db) {}
|
||||
DLDatabase(Reference<FdbCApi> api, FdbCApi::FDBDatabase *db) : api(api), db(db), ready(Void()) {}
|
||||
DLDatabase(Reference<FdbCApi> api, ThreadFuture<FdbCApi::FDBDatabase*> dbFuture);
|
||||
~DLDatabase() { api->databaseDestroy(db); }
|
||||
|
||||
ThreadFuture<Void> onReady();
|
||||
|
||||
Reference<ITransaction> createTransaction();
|
||||
void setOption(FDBDatabaseOptions::Option option, Optional<StringRef> value = Optional<StringRef>());
|
||||
|
||||
|
@ -170,7 +173,8 @@ public:
|
|||
|
||||
private:
|
||||
const Reference<FdbCApi> api;
|
||||
FdbCApi::FDBDatabase* const db;
|
||||
FdbCApi::FDBDatabase* db; // Always set if API version >= 610, otherwise guaranteed to be set when onReady future is set
|
||||
ThreadFuture<Void> ready;
|
||||
};
|
||||
|
||||
class DLApi : public IClientApi {
|
||||
|
@ -185,7 +189,8 @@ public:
|
|||
void runNetwork();
|
||||
void stopNetwork();
|
||||
|
||||
ThreadFuture<Reference<IDatabase>> createDatabase(const char *clusterFilePath);
|
||||
Reference<IDatabase> createDatabase(const char *clusterFilePath);
|
||||
Reference<IDatabase> createDatabase609(const char *clusterFilePath); // legacy database creation
|
||||
|
||||
void addNetworkThreadCompletionHook(void (*hook)(void*), void *hookParameter);
|
||||
|
||||
|
@ -327,7 +332,6 @@ private:
|
|||
Reference<IDatabase> db;
|
||||
const Reference<ThreadSafeAsyncVar<Reference<IDatabase>>> dbVar;
|
||||
|
||||
ThreadFuture<Reference<IDatabase>> dbFuture;
|
||||
ThreadFuture<Void> changed;
|
||||
|
||||
bool cancelled;
|
||||
|
@ -355,7 +359,7 @@ public:
|
|||
void stopNetwork();
|
||||
void addNetworkThreadCompletionHook(void (*hook)(void*), void *hookParameter);
|
||||
|
||||
ThreadFuture<Reference<IDatabase>> createDatabase(const char *clusterFilePath);
|
||||
Reference<IDatabase> createDatabase(const char *clusterFilePath);
|
||||
static MultiVersionApi* api;
|
||||
|
||||
Reference<ClientInfo> getLocalClient();
|
||||
|
|
|
@ -486,6 +486,8 @@ DatabaseContext::DatabaseContext(
|
|||
clientStatusUpdater.actor = clientStatusUpdateActor(this);
|
||||
}
|
||||
|
||||
DatabaseContext::DatabaseContext( const Error &err ) : deferredError(err), latencies(1000), readLatencies(1000), commitLatencies(1000), GRVLatencies(1000), mutationsPerCommit(1000), bytesPerCommit(1000) {}
|
||||
|
||||
ACTOR static Future<Void> monitorClientInfo( Reference<AsyncVar<Optional<ClusterInterface>>> clusterInterface, Reference<ClusterConnectionFile> ccf, Reference<AsyncVar<ClientDBInfo>> outInfo ) {
|
||||
try {
|
||||
state Optional<std::string> incorrectConnectionString;
|
||||
|
@ -1855,8 +1857,9 @@ Transaction::Transaction( Database const& cx )
|
|||
: cx(cx), info(cx->taskID), backoff(CLIENT_KNOBS->DEFAULT_BACKOFF), committedVersion(invalidVersion), versionstampPromise(Promise<Standalone<StringRef>>()), numErrors(0), trLogInfo(createTrLogInfoProbabilistically(cx))
|
||||
{
|
||||
setPriority(GetReadVersionRequest::PRIORITY_DEFAULT);
|
||||
if(cx->lockAware)
|
||||
if(cx->lockAware) {
|
||||
options.lockAware = true;
|
||||
}
|
||||
}
|
||||
|
||||
Transaction::~Transaction() {
|
||||
|
@ -3049,11 +3052,14 @@ Future< Standalone<VectorRef<KeyRef>> > Transaction::splitStorageMetrics( KeyRan
|
|||
void Transaction::checkDeferredError() { cx->checkDeferredError(); }
|
||||
|
||||
Reference<TransactionLogInfo> Transaction::createTrLogInfoProbabilistically(const Database &cx) {
|
||||
double clientSamplingProbability = std::isinf(cx->clientInfo->get().clientTxnInfoSampleRate) ? CLIENT_KNOBS->CSI_SAMPLING_PROBABILITY : cx->clientInfo->get().clientTxnInfoSampleRate;
|
||||
if (((networkOptions.logClientInfo.present() && networkOptions.logClientInfo.get()) || BUGGIFY) && g_random->random01() < clientSamplingProbability && (!g_network->isSimulated() || !g_simulator.speedUpSimulation))
|
||||
return Reference<TransactionLogInfo>(new TransactionLogInfo());
|
||||
else
|
||||
return Reference<TransactionLogInfo>();
|
||||
if(!cx->isError()) {
|
||||
double clientSamplingProbability = std::isinf(cx->clientInfo->get().clientTxnInfoSampleRate) ? CLIENT_KNOBS->CSI_SAMPLING_PROBABILITY : cx->clientInfo->get().clientTxnInfoSampleRate;
|
||||
if (((networkOptions.logClientInfo.present() && networkOptions.logClientInfo.get()) || BUGGIFY) && g_random->random01() < clientSamplingProbability && (!g_network->isSimulated() || !g_simulator.speedUpSimulation)) {
|
||||
return Reference<TransactionLogInfo>(new TransactionLogInfo());
|
||||
}
|
||||
}
|
||||
|
||||
return Reference<TransactionLogInfo>();
|
||||
}
|
||||
|
||||
void enableClientInfoLogging() {
|
||||
|
|
|
@ -1097,7 +1097,7 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
ReadYourWritesTransaction::ReadYourWritesTransaction( Database const& cx ) : cache(&arena), writes(&arena), tr(cx), retries(0), creationTime(now()), commitStarted(false), options(tr) {}
|
||||
ReadYourWritesTransaction::ReadYourWritesTransaction( Database const& cx ) : cache(&arena), writes(&arena), tr(cx), retries(0), creationTime(now()), commitStarted(false), options(tr), deferredError(cx->deferredError) {}
|
||||
|
||||
ACTOR Future<Void> timebomb(double totalSeconds, Promise<Void> resetPromise) {
|
||||
if(totalSeconds == 0.0) {
|
||||
|
|
|
@ -30,20 +30,8 @@
|
|||
// Users of ThreadSafeTransaction might share Reference<ThreadSafe...> between different threads as long as they don't call addRef (e.g. C API follows this).
|
||||
// Therefore, it is unsafe to call (explicitly or implicitly) this->addRef in any of these functions.
|
||||
|
||||
Reference<IDatabase> constructThreadSafeDatabase( Database db ) {
|
||||
return Reference<IDatabase>( new ThreadSafeDatabase(db.extractPtr()) );
|
||||
}
|
||||
Future<Reference<IDatabase>> createThreadSafeDatabase( std::string connFilename, int apiVersion ) {
|
||||
Database db = Database::createDatabase( connFilename, apiVersion );
|
||||
return constructThreadSafeDatabase( db );
|
||||
}
|
||||
ThreadFuture<Reference<IDatabase>> ThreadSafeDatabase::create( std::string connFilename, int apiVersion ) {
|
||||
if (!g_network) return ThreadFuture<Reference<IDatabase>>(network_not_setup());
|
||||
return onMainThread( [connFilename, apiVersion](){ return createThreadSafeDatabase( connFilename, apiVersion ); } );
|
||||
}
|
||||
ThreadFuture<Void> ThreadSafeDatabase::onConnected() {
|
||||
DatabaseContext* db = this->db;
|
||||
return onMainThread( [db]() -> Future<Void> {
|
||||
return onMainThread( [this]() -> Future<Void> {
|
||||
db->checkDeferredError();
|
||||
return db->onConnected();
|
||||
} );
|
||||
|
@ -52,31 +40,45 @@ ThreadFuture<Void> ThreadSafeDatabase::onConnected() {
|
|||
ThreadFuture<Reference<IDatabase>> ThreadSafeDatabase::createFromExistingDatabase(Database db) {
|
||||
return onMainThread( [db](){
|
||||
db->checkDeferredError();
|
||||
return Future<Reference<IDatabase>>(constructThreadSafeDatabase(db));
|
||||
DatabaseContext *cx = db.getPtr();
|
||||
cx->addref();
|
||||
return Future<Reference<IDatabase>>(Reference<IDatabase>(new ThreadSafeDatabase(cx)));
|
||||
});
|
||||
}
|
||||
|
||||
Reference<ITransaction> ThreadSafeDatabase::createTransaction() {
|
||||
return Reference<ITransaction>(new ThreadSafeTransaction(this));
|
||||
}
|
||||
|
||||
Database ThreadSafeDatabase::unsafeGetDatabase() const {
|
||||
db->addref();
|
||||
return Database(db);
|
||||
return Reference<ITransaction>(new ThreadSafeTransaction(Reference<ThreadSafeDatabase>::addRef(this)));
|
||||
}
|
||||
|
||||
void ThreadSafeDatabase::setOption( FDBDatabaseOptions::Option option, Optional<StringRef> value) {
|
||||
DatabaseContext *db = this->db;
|
||||
Standalone<Optional<StringRef>> passValue = value;
|
||||
onMainThreadVoid( [db, option, passValue](){ db->setOption(option, passValue.contents()); }, &db->deferredError );
|
||||
onMainThreadVoid( [this, option, passValue](){ db->setOption(option, passValue.contents()); }, &db->deferredError );
|
||||
}
|
||||
|
||||
ThreadSafeDatabase::ThreadSafeDatabase(std::string connFilename, int apiVersion) {
|
||||
db = NULL; // All accesses to db happen on the main thread, so this pointer will be set by the time anybody uses it
|
||||
|
||||
Reference<ClusterConnectionFile> connFile = Reference<ClusterConnectionFile>(new ClusterConnectionFile(ClusterConnectionFile::lookupClusterFileName(connFilename).first));
|
||||
onMainThreadVoid([this, connFile, apiVersion](){
|
||||
try {
|
||||
Database db = Database::createDatabase(connFile, apiVersion);
|
||||
this->db = db.extractPtr();
|
||||
}
|
||||
catch(Error &e) {
|
||||
this->db = new DatabaseContext(e);
|
||||
}
|
||||
catch(...) {
|
||||
this->db = new DatabaseContext(unknown_error());
|
||||
}
|
||||
}, NULL);
|
||||
}
|
||||
|
||||
ThreadSafeDatabase::~ThreadSafeDatabase() {
|
||||
DatabaseContext* db = this->db;
|
||||
DatabaseContext *db = this->db;
|
||||
onMainThreadVoid( [db](){ db->delref(); }, NULL );
|
||||
}
|
||||
|
||||
ThreadSafeTransaction::ThreadSafeTransaction( ThreadSafeDatabase *cx ) {
|
||||
ThreadSafeTransaction::ThreadSafeTransaction( Reference<ThreadSafeDatabase> db ) {
|
||||
// Allocate memory for the transaction from this thread (so the pointer is known for subsequent method calls)
|
||||
// but run its constructor on the main thread
|
||||
|
||||
|
@ -84,10 +86,12 @@ ThreadSafeTransaction::ThreadSafeTransaction( ThreadSafeDatabase *cx ) {
|
|||
// because the reference count of the DatabaseContext is solely managed from the main thread. If cx is destructed
|
||||
// immediately after this call, it will defer the DatabaseContext::delref (and onMainThread preserves the order of
|
||||
// these operations).
|
||||
DatabaseContext* db = cx->db;
|
||||
ReadYourWritesTransaction *tr = this->tr = ReadYourWritesTransaction::allocateOnForeignThread();
|
||||
// No deferred error -- if the construction of the RYW transaction fails, we have no where to put it
|
||||
onMainThreadVoid( [tr,db](){ db->addref(); new (tr) ReadYourWritesTransaction( Database(db) ); }, NULL );
|
||||
onMainThreadVoid( [tr, db](){
|
||||
db->db->addref();
|
||||
new (tr) ReadYourWritesTransaction( Database(db->db) );
|
||||
}, NULL );
|
||||
}
|
||||
|
||||
ThreadSafeTransaction::~ThreadSafeTransaction() {
|
||||
|
@ -357,8 +361,8 @@ void ThreadSafeApi::stopNetwork() {
|
|||
::stopNetwork();
|
||||
}
|
||||
|
||||
ThreadFuture<Reference<IDatabase>> ThreadSafeApi::createDatabase(const char *clusterFilePath) {
|
||||
return ThreadSafeDatabase::create(clusterFilePath, apiVersion);
|
||||
Reference<IDatabase> ThreadSafeApi::createDatabase(const char *clusterFilePath) {
|
||||
return Reference<IDatabase>(new ThreadSafeDatabase(clusterFilePath, apiVersion));
|
||||
}
|
||||
|
||||
void ThreadSafeApi::addNetworkThreadCompletionHook(void (*hook)(void*), void *hookParameter) {
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
class ThreadSafeDatabase : public IDatabase, public ThreadSafeReferenceCounted<ThreadSafeDatabase> {
|
||||
public:
|
||||
~ThreadSafeDatabase();
|
||||
static ThreadFuture<Reference<IDatabase>> create( std::string connFilename, int apiVersion=-1 );
|
||||
static ThreadFuture<Reference<IDatabase>> createFromExistingDatabase(Database cx);
|
||||
|
||||
Reference<ITransaction> createTransaction();
|
||||
|
@ -46,14 +45,14 @@ private:
|
|||
friend class ThreadSafeTransaction;
|
||||
DatabaseContext* db;
|
||||
public: // Internal use only
|
||||
ThreadSafeDatabase( std::string connFilename, int apiVersion );
|
||||
ThreadSafeDatabase( DatabaseContext* db ) : db(db) {}
|
||||
DatabaseContext* unsafeGetPtr() const { return db; }
|
||||
Database unsafeGetDatabase() const; // This is thread unsafe (ONLY call from the network thread), but respects reference counting
|
||||
};
|
||||
|
||||
class ThreadSafeTransaction : public ITransaction, ThreadSafeReferenceCounted<ThreadSafeTransaction>, NonCopyable {
|
||||
public:
|
||||
explicit ThreadSafeTransaction( ThreadSafeDatabase *cx );
|
||||
explicit ThreadSafeTransaction( Reference<ThreadSafeDatabase> db );
|
||||
~ThreadSafeTransaction();
|
||||
|
||||
void cancel();
|
||||
|
@ -119,7 +118,7 @@ public:
|
|||
void runNetwork();
|
||||
void stopNetwork();
|
||||
|
||||
ThreadFuture<Reference<IDatabase>> createDatabase(const char *clusterFilePath);
|
||||
Reference<IDatabase> createDatabase(const char *clusterFilePath);
|
||||
|
||||
void addNetworkThreadCompletionHook(void (*hook)(void*), void *hookParameter);
|
||||
|
||||
|
|
|
@ -85,8 +85,6 @@ namespace vexillographer
|
|||
{
|
||||
{ Scope.NetworkOption, new ScopeOptions(true,
|
||||
"A set of options that can be set globally for the {@link FDB FoundationDB API}.") },
|
||||
{ Scope.ClusterOption, new ScopeOptions(true,
|
||||
"A set of options that can be set on a {@link Cluster}.") },
|
||||
{ Scope.DatabaseOption, new ScopeOptions(true,
|
||||
"A set of options that can be set on a {@link Database}.") },
|
||||
{ Scope.TransactionOption, new ScopeOptions(true,
|
||||
|
|
|
@ -30,7 +30,6 @@ namespace vexillographer
|
|||
public enum Scope
|
||||
{
|
||||
NetworkOption,
|
||||
ClusterOption,
|
||||
DatabaseOption,
|
||||
TransactionOption,
|
||||
StreamingMode,
|
||||
|
@ -172,8 +171,6 @@ namespace vexillographer
|
|||
{
|
||||
case Scope.NetworkOption:
|
||||
return "NET_OPTION";
|
||||
case Scope.ClusterOption:
|
||||
return "CLUSTER_OPTION";
|
||||
case Scope.DatabaseOption:
|
||||
return "DB_OPTION";
|
||||
case Scope.TransactionOption:
|
||||
|
|
Loading…
Reference in New Issue