Wrapper around ScyllaDB's Rust Driver, which is API-compatible with both ScyllaDB and Datastax C/C++ Driver and may be considered a drop-in replacement (with some minor limitations, see Limitations).
In this section we will go over most important CMake options and what each of them controls.
CASS_BUILD_SHARED- Build shared driver library (.so).ONby default.CASS_BUILD_STATIC- Build static driver library (.a).ONby default.CASS_BUILD_INTEGRATION_TESTS- Build integration tests (seeTestingsection below)OFFby default.CASS_BUILD_EXAMPLES- Build examples (seeExamplessection below).OFFby default.CASS_USE_STATIC_LIBS- Link against static libraries when building tests/examples.OFFby default.CMAKE_BUILD_TYPE- Controls the cargo profile library is built with. Possible values are:Debug,RelWithDebInfoandRelease. Default value isDebug. For more information, see the profiles definitions inscylla-rust-wrapper/Cargo.toml.
For example, to build a shared driver library (no static library) in release mode and integration tests you can do:
mkdir build
cd build
cmake -DCASS_BUILD_STATIC=OFF -DCASS_BUILD_INTEGRATION_TESTS=ON -DCMAKE_BUILD_TYPE=Release ..
makeThere are some examples in the examples directory. To run a single example:
cd examples/cloud
gcc cloud.c PATH_TO_CPP_RUST/scylla-rust-wrapper/target/debug/libscylla_cpp_driver.so -Wl,-rpath,PATH_TO_CPP_RUST/build -I PATH_TO_CPP_RUST/include -o cloud
./cloud path_to_connection_bundle username password#include <cassandra.h>
#include <stdio.h>
int main(int argc, char* argv[]) {
/* Setup and connect to cluster */
CassFuture* connect_future = NULL;
CassCluster* cluster = cass_cluster_new();
CassSession* session = cass_session_new();
char* hosts = "127.0.0.1";
if (argc > 1) {
hosts = argv[1];
}
/* Add contact points */
cass_cluster_set_contact_points(cluster, hosts);
/* Provide the cluster object as configuration to connect the session */
connect_future = cass_session_connect(session, cluster);
if (cass_future_error_code(connect_future) == CASS_OK) {
CassFuture* close_future = NULL;
/* Build statement and execute query */
const char* query = "SELECT release_version FROM system.local WHERE key='local'";
CassStatement* statement = cass_statement_new(query, 0);
CassFuture* result_future = cass_session_execute(session, statement);
if (cass_future_error_code(result_future) == CASS_OK) {
/* Retrieve result set and get the first row */
const CassResult* result = cass_future_get_result(result_future);
const CassRow* row = cass_result_first_row(result);
if (row) {
const CassValue* value = cass_row_get_column_by_name(row, "release_version");
const char* release_version;
size_t release_version_length;
cass_value_get_string(value, &release_version, &release_version_length);
printf("release_version: '%.*s'\n", (int)release_version_length, release_version);
}
cass_result_free(result);
} else {
/* Handle error */
const char* message;
size_t message_length;
cass_future_error_message(result_future, &message, &message_length);
fprintf(stderr, "Unable to run query: '%.*s'\n", (int)message_length, message);
}
cass_statement_free(statement);
cass_future_free(result_future);
/* Close the session */
close_future = cass_session_close(session);
cass_future_wait(close_future);
cass_future_free(close_future);
} else {
/* Handle error */
const char* message;
size_t message_length;
cass_future_error_message(connect_future, &message, &message_length);
fprintf(stderr, "Unable to connect: '%.*s'\n", (int)message_length, message);
}
cass_future_free(connect_future);
cass_cluster_free(cluster);
cass_session_free(session);
return 0;
}The logging API and implementation are compatible with the C++ driver, for more details please refer to the logging documentation.
As the tracing framework is used under the hood to instrument the collection of logs from the Rust driver and the scylla-rust-wrapper,
the logging level and callback are passed through a custom event subscriber which is globally set as default when cass_log_set_level is called.
So, cass_log_set_level must be called only once as subsequent attempts trying to modify the globally set event subscriber will be ignored.
Also, Rust programs using CPP RS Driver under the hood must avoid calling tracing::subscriber::set_global_default as this will cause conflicts.
Note: The logging configuration must be done before any other driver function is called, otherwise, the default logging callback will be used, and logs will appear on stderr.
void on_log(const CassLogMessage* message, void* data) {
/* Handle logging */
}
int main() {
void* log_data = NULL /* Custom log resource */;
cass_log_set_callback(on_log, log_data);
cass_log_set_level(CASS_LOG_INFO);
/* Create cluster and connect session */
}The driver inherits almost all the features of C/C++ and Rust drivers, such as:
- Asynchronous API
- Shard-aware routing
- Simple, Prepared and Batch statements
- Query paging
- CQL binary protocol version 4
- Load balancing policies
- Retry policies
- SSL
- Authentication
- Tuples and UDTs
- Nested collections
- Data types
- Schema metadata (keyspace metadata, materialized views, etc.)
Note: This section may be incomplete, so not everything that is not fully supported is mentioned here.
| Function | Description |
|---|---|
| Statement | |
| cass_statement_bind_custom[by_name] | Binding is not implemented for custom types in the Rust driver. |
| Collection | |
| cass_collection_append_custom[_n] | Unimplemented because of the same reasons as binding for statements. Note: The driver does not check whether the type of the appended value is compatible with the type of the collection items. |
| User Defined Type | |
| cass_user_type_set_custom[by_name] | Unimplemented because of the same reasons as binding for statements. Note: The driver does not check whether the type of the value being set for a field of the UDT is compatible with the field's actual type. |
| Metadata | |
| cass_keyspace_meta_is_virtual | UDF, Aggregate and Index are not supported in the Rust driver, yet. |
| cass_table_meta_is_virtual | |
| cass_table_meta_clustering_key_order | |
| cass_materialized_view_meta_clustering_key_order | |
| cass_function_* | |
| cass_aggregate_* | |
| cass_index_* | |
- cass_aggregate_meta_argument_count
- cass_aggregate_meta_argument_type
- cass_aggregate_meta_field_by_name
- cass_aggregate_meta_field_by_name_n
- cass_aggregate_meta_final_func
- cass_aggregate_meta_full_name
- cass_aggregate_meta_init_cond
- cass_aggregate_meta_name
- cass_aggregate_meta_return_type
- cass_aggregate_meta_state_func
- cass_aggregate_meta_state_type
- cass_alloc_set_functions
- cass_authenticator_address
- cass_authenticator_class_name
- cass_authenticator_exchange_data
- cass_authenticator_hostname
- cass_authenticator_response
- cass_authenticator_set_error
- cass_authenticator_set_error_n
- cass_authenticator_set_exchange_data
- cass_authenticator_set_response
- cass_batch_set_custom_payload
- cass_batch_set_keyspace
- cass_batch_set_keyspace_n
- cass_cluster_set_authenticator_callbacks
- cass_cluster_set_cloud_secure_connection_bundle
- cass_cluster_set_cloud_secure_connection_bundle_n
- cass_cluster_set_cloud_secure_connection_bundle_no_ssl_lib_init
- cass_cluster_set_cloud_secure_connection_bundle_no_ssl_lib_init_n
- cass_cluster_set_constant_reconnect
- cass_cluster_set_exponential_reconnect
- cass_cluster_set_host_listener_callback
- cass_cluster_set_max_concurrent_creation
- cass_cluster_set_max_concurrent_requests_threshold
- cass_cluster_set_max_connections_per_host
- cass_cluster_set_max_requests_per_flush
- cass_cluster_set_max_reusable_write_objects
- cass_cluster_set_monitor_reporting_interval
- cass_cluster_set_new_request_ratio
- cass_cluster_set_no_compact
- cass_cluster_set_pending_requests_high_water_mark
- cass_cluster_set_pending_requests_low_water_mark
- cass_cluster_set_prepare_on_all_hosts
- cass_cluster_set_prepare_on_up_or_add_host
- cass_cluster_set_queue_size_event
- cass_cluster_set_queue_size_io
- cass_cluster_set_reconnect_wait_time
- cass_cluster_set_resolve_timeout
- cass_cluster_set_tracing_consistency
- cass_cluster_set_tracing_max_wait_time
- cass_cluster_set_tracing_retry_wait_time
- cass_cluster_set_use_hostname_resolution
- cass_cluster_set_use_randomized_contact_points
- cass_cluster_set_write_bytes_high_water_mark
- cass_cluster_set_write_bytes_low_water_mark
- cass_collection_append_custom
- cass_collection_append_custom_n
- cass_column_meta_field_by_name
- cass_column_meta_field_by_name_n
- cass_custom_payload_free
- cass_custom_payload_new
- cass_custom_payload_remove
- cass_custom_payload_remove_n
- cass_custom_payload_set
- cass_custom_payload_set_n
- cass_function_meta_argument
- cass_function_meta_argument_count
- cass_function_meta_argument_type_by_name
- cass_function_meta_argument_type_by_name_n
- cass_function_meta_body
- cass_function_meta_body
- cass_function_meta_called_on_null_input
- cass_function_meta_field_by_name
- cass_function_meta_field_by_name_n
- cass_function_meta_full_name
- cass_function_meta_language
- cass_function_meta_name
- cass_function_meta_return_type
- cass_future_custom_payload_item
- cass_future_custom_payload_item_count
- cass_index_meta_field_by_name
- cass_index_meta_field_by_name_n
- cass_index_meta_name
- cass_index_meta_options
- cass_index_meta_target
- cass_index_meta_type
- cass_iterator_aggregates_from_keyspace_meta
- cass_iterator_fields_from_aggregate_meta
- cass_iterator_fields_from_column_meta
- cass_iterator_fields_from_function_meta
- cass_iterator_fields_from_index_meta
- cass_iterator_fields_from_keyspace_meta
- cass_iterator_fields_from_materialized_view_meta
- cass_iterator_fields_from_table_meta
- cass_iterator_functions_from_keyspace_meta
- cass_iterator_get_aggregate_meta
- cass_iterator_get_function_meta
- cass_iterator_get_index_meta
- cass_iterator_get_meta_field_name
- cass_iterator_get_meta_field_value
- cass_iterator_indexes_from_table_meta
- cass_keyspace_meta_aggregate_by_name
- cass_keyspace_meta_aggregate_by_name_n
- cass_keyspace_meta_field_by_name
- cass_keyspace_meta_field_by_name_n
- cass_keyspace_meta_function_by_name
- cass_keyspace_meta_function_by_name_n
- cass_keyspace_meta_is_virtual
- cass_materialized_view_meta_clustering_key_order
- cass_materialized_view_meta_field_by_name
- cass_materialized_view_meta_field_by_name_n
- cass_schema_meta_snapshot_version
- cass_schema_meta_version
- cass_session_get_speculative_execution_metrics
- cass_statement_add_key_index
- cass_statement_bind_custom
- cass_statement_bind_custom_by_name
- cass_statement_bind_custom_by_name_n
- cass_statement_bind_custom_n
- cass_statement_set_custom_payload
- cass_statement_set_keyspace
- cass_statement_set_keyspace_n
- cass_table_meta_clustering_key_order
- cass_table_meta_field_by_name
- cass_table_meta_field_by_name_n
- cass_table_meta_index
- cass_table_meta_index_by_name
- cass_table_meta_index_by_name_n
- cass_table_meta_index_count
- cass_table_meta_is_virtual
- cass_tuple_set_custom
- cass_tuple_set_custom_n
- cass_value_get_custom
Integration tests from the original cpp-driver are compilable but not all tests pass yet.
Some tests are added to GitHub Actions workflows and are used to test every pull request on both ScyllaDB and Cassandra clusters.
To build and run the integration tests several requirements need to be met:
- Install
libuvandopensslon your system:
# On Ubuntu
sudo apt-get install libuv1-dev
sudo apt-get install libssl1.0.0
# On Fedora
sudo dnf install libuv-devel
sudo dnf install openssl-devel- Clone and install scylla-ccm system-wide.
Finally, to build the integration tests:
mkdir build && cd build
cmake -DCASS_BUILD_INTEGRATION_TESTS=ON .. && make
Now, use --gtest_filter to run certain integration tests:
./cassandra-integration-tests --scylla --version=<SCYLLA_VERSION> --category=CASSANDRA --verbose=ccm --gtest_filter="ClusterTests.*"Note: Tests that pass with ScyllaDB and Cassandra clusters can be found in Makefile: SCYLLA_TEST_FILTER and CASSANDRA_TEST_FILTER env variables.
The project uses CPack to produce installable artifacts for Linux, macOS, and Windows. Start by configuring and building the project:
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build --config ReleaseFrom the build directory you can invoke cpack with the generator that
matches your target platform:
-
Linux (Debian/Ubuntu/Fedora/Rocky):
cpack -G DEB -C Release # produces .deb in build/ cpack -G RPM -C Release # produces .rpm in build/
Debian packages set shlibdeps automatically; RPM packages target the
Applications/Databasesgroup and use release number1by default. -
macOS (pkg / dmg):
cpack -G productbuild -C Release # generates .pkg cpack -G DragNDrop -C Release # generates .dmg
Both outputs bundle the compiled libraries alongside headers and pkg-config manifests.
-
Windows (MSI):
cpack -G WIX -C Release # requires WiX Toolset 3.11+
The MSI installs into
Program Files\ScyllaDB\Scylla CPP Driverand reuses a stable upgrade GUID for seamless upgrades.
GitHub Actions can exercise the same flow via the reusable workflow defined in
.github/workflows/build-cpack-packages.yml. Releases published through
.github/workflows/release-upload-packages.yml automatically upload the
generated artifacts.
- Slack: http://slack.scylladb.com/
Issuessection of GitHub repository
- CQL binary protocol version 4
This project is licensed under the GNU Lesser General Public License v2.1