diff --git a/.github/workflows/build-lint-and-test.yml b/.github/workflows/build-lint-and-test.yml index 500fa5c35..2191ccc06 100644 --- a/.github/workflows/build-lint-and-test.yml +++ b/.github/workflows/build-lint-and-test.yml @@ -38,6 +38,9 @@ jobs: - name: Run unit and proxy tests run: make run-test-unit + - name: Run examples + run: make run-examples-scylla + - name: Build integration test binary id: build-integration-test-bin run: make build-integration-test-bin diff --git a/CMakeLists.txt b/CMakeLists.txt index a34197a6f..407d675e1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -69,6 +69,10 @@ if(CASS_BUILD_INTEGRATION_TESTS OR CASS_BUILD_UNIT_TESTS) set(CASS_USE_LIBUV ON) endif() +if(CASS_BUILD_EXAMPLES) + set(CASS_USE_LIBUV ON) # Some examples require libuv, e.g. "callbacks". +endif() + # Determine which driver target should be used as a dependency set(PROJECT_LIB_NAME_TARGET scylla-cpp-driver) if(CASS_USE_STATIC_LIBS OR diff --git a/Makefile b/Makefile index 0a85f81e2..f6a665554 100644 --- a/Makefile +++ b/Makefile @@ -122,6 +122,42 @@ CASSANDRA_NO_VALGRIND_TEST_FILTER := $(subst ${SPACE},${EMPTY},AsyncTests.Integr :HeartbeatTests.Integration_Cassandra_HeartbeatFailed) endif +ifndef SCYLLA_EXAMPLES_URI +# In sync with the docker compose file. +SCYLLA_EXAMPLES_URI := 172.43.0.2 +endif + +ifndef SCYLLA_EXAMPLES_TO_RUN +SCYLLA_EXAMPLES_TO_RUN := \ + async \ + basic \ + batch \ + bind_by_name \ + callbacks \ + collections \ + concurrent_executions \ + date_time \ + duration \ + maps \ + named_parameters \ + paging \ + prepared \ + simple \ + ssl \ + tracing \ + tuple \ + udt \ + uuids \ + + # auth <- unimplemented `cass_cluster_set_authenticator_callbacks()` + # execution_profiles <- unimplemented `cass_statement_set_keyspace()` + # host_listener <- unimplemented `cass_cluster_set_host_listener_callback()` + # logging <- unimplemented `cass_cluster_set_host_listener_callback()` + # perf <- unimplemented `cass_cluster_set_num_threads_io()`, `cass_cluster_set_queue_size_io()` + # schema_meta <- unimplemented multiple schema-related functions + # cloud <- out of interest for us, not related to ScyllaDB +endif + ifndef CCM_COMMIT_ID export CCM_COMMIT_ID := master endif @@ -216,6 +252,14 @@ build-integration-test-bin-if-missing: cmake -DCASS_BUILD_INTEGRATION_TESTS=ON -DCMAKE_BUILD_TYPE=Release .. && (make -j 4 || make);\ } +build-examples: + @{\ + echo "Building examples to ${EXAMPLES_DIR}";\ + mkdir "${BUILD_DIR}" >/dev/null 2>&1 || true;\ + cd "${BUILD_DIR}";\ + cmake -DCASS_BUILD_INTEGRATION_TESTS=off -DCASS_BUILD_EXAMPLES=on -DCMAKE_BUILD_TYPE=Release .. && (make -j 4 || make);\ + } + _update-rust-tooling: @echo "Run rustup update" @rustup update @@ -298,3 +342,28 @@ endif run-test-unit: install-cargo-if-missing _update-rust-tooling @cd ${CURRENT_DIR}/scylla-rust-wrapper; RUSTFLAGS="${FULL_RUSTFLAGS}" cargo test + +# Currently not used. +CQLSH := cqlsh + +run-examples-scylla: build-examples + @sudo sh -c "echo 2097152 >> /proc/sys/fs/aio-max-nr" + @# Keep `SCYLLA_EXAMPLES_URI` in sync with the `scylla` service in `docker-compose.yml`. + @docker compose -f tests/examples_cluster/docker-compose.yml up -d --wait + + @# Instead of using cqlsh, which would impose another dependency on the system, + @# we use a special example `drop_examples_keyspace` to drop the `examples` keyspace. + @# CQLSH_HOST=${SCYLLA_EXAMPLES_URI} ${CQLSH} -e "DROP KEYSPACE IF EXISTS EXAMPLES"; \ + + @echo "Running examples on scylla ${SCYLLA_VERSION}" + @for example in ${SCYLLA_EXAMPLES_TO_RUN} ; do \ + echo -e "\nRunning example: $${example}"; \ + build/examples/drop_examples_keyspace/drop_examples_keyspace ${SCYLLA_EXAMPLES_URI} || exit 1; \ + build/examples/$${example}/$${example} ${SCYLLA_EXAMPLES_URI} || { \ + echo "Example \`$${example}\` has failed!"; \ + docker compose -f tests/examples_cluster/docker-compose.yml down; \ + exit 42; \ + }; \ + done + + @docker compose -f tests/examples_cluster/docker-compose.yml down --remove-orphans diff --git a/examples/drop_examples_keyspace/.gitignore b/examples/drop_examples_keyspace/.gitignore new file mode 100644 index 000000000..c8b1d06b5 --- /dev/null +++ b/examples/drop_examples_keyspace/.gitignore @@ -0,0 +1 @@ +drop_examples_keyspace diff --git a/examples/dse/date_range/CMakeLists.txt b/examples/drop_examples_keyspace/CMakeLists.txt similarity index 87% rename from examples/dse/date_range/CMakeLists.txt rename to examples/drop_examples_keyspace/CMakeLists.txt index 28af404bd..d56a29a32 100644 --- a/examples/dse/date_range/CMakeLists.txt +++ b/examples/drop_examples_keyspace/CMakeLists.txt @@ -1,12 +1,12 @@ cmake_minimum_required(VERSION 3.15) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ".") -set(PROJECT_EXAMPLE_NAME date_range) +set(PROJECT_EXAMPLE_NAME drop_examples_keyspace) file(GLOB EXAMPLE_SRC_FILES *.c) include_directories(${INCLUDES}) add_executable(${PROJECT_EXAMPLE_NAME} ${EXAMPLE_SRC_FILES}) -target_link_libraries(${PROJECT_EXAMPLE_NAME} ${PROJECT_LIB_NAME_TARGET} ${DSE_LIBS}) +target_link_libraries(${PROJECT_EXAMPLE_NAME} ${PROJECT_LIB_NAME_TARGET} ${CASS_LIBS}) add_dependencies(${PROJECT_EXAMPLE_NAME} ${PROJECT_LIB_NAME_TARGET}) set_target_properties(${PROJECT_EXAMPLE_NAME} PROPERTIES FOLDER "Examples" diff --git a/examples/dse/gssapi/gssapi.c b/examples/drop_examples_keyspace/drop_examples_keyspace.c similarity index 54% rename from examples/dse/gssapi/gssapi.c rename to examples/drop_examples_keyspace/drop_examples_keyspace.c index 476f1de06..cbeea5d02 100644 --- a/examples/dse/gssapi/gssapi.c +++ b/examples/drop_examples_keyspace/drop_examples_keyspace.c @@ -25,54 +25,77 @@ For more information, please refer to */ -#include - #include -#include +#include -int main(int argc, char* argv[]) { - /* Setup and connect to cluster */ - CassFuture* connect_future = NULL; +#include "cassandra.h" + +void print_error(CassFuture* future) { + const char* message; + size_t message_length; + cass_future_error_message(future, &message, &message_length); + fprintf(stderr, "Error: %.*s\n", (int)message_length, message); +} + +CassCluster* create_cluster(const char* hosts) { CassCluster* cluster = cass_cluster_new(); - CassSession* session = cass_session_new(); - char* hosts = "127.0.0.1"; - if (argc > 1) { - hosts = argv[1]; + cass_cluster_set_contact_points(cluster, hosts); + return cluster; +} + +CassError connect_session(CassSession* session, const CassCluster* cluster) { + CassError rc = CASS_OK; + CassFuture* future = cass_session_connect(session, cluster); + + cass_future_wait(future); + rc = cass_future_error_code(future); + if (rc != CASS_OK) { + print_error(future); } + cass_future_free(future); - cass_log_set_level(CASS_LOG_INFO); + return rc; +} - /* Add contact points */ - cass_cluster_set_contact_points(cluster, hosts); +CassError execute_query(CassSession* session, const char* query) { + CassError rc = CASS_OK; + CassFuture* future = NULL; + CassStatement* statement = cass_statement_new(query, 0); - /* Hostname resolution is typically necessary when authenticating with Kerberos. */ - cass_cluster_set_use_hostname_resolution(cluster, cass_true); + future = cass_session_execute(session, statement); + cass_future_wait(future); - cass_cluster_set_dse_gssapi_authenticator(cluster, "dse", "cassandra@DATASTAX.COM"); + rc = cass_future_error_code(future); + if (rc != CASS_OK) { + print_error(future); + } - /* Provide the cluster object as configuration to connect the session */ - connect_future = cass_session_connect(session, cluster); + cass_future_free(future); + cass_statement_free(statement); - if (cass_future_error_code(connect_future) == CASS_OK) { - CassFuture* close_future = NULL; + return rc; +} - printf("Successfully connected!\n"); +int main(int argc, char* argv[]) { + CassCluster* cluster = NULL; + CassSession* session = cass_session_new(); + char* hosts = "127.0.0.1"; - /* 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); + if (argc > 1) { + hosts = argv[1]; } + cluster = create_cluster(hosts); + + if (connect_session(session, cluster) != CASS_OK) { + cass_cluster_free(cluster); + cass_session_free(session); + return -1; + } + + execute_query(session, "DROP KEYSPACE IF EXISTS examples"); - cass_future_free(connect_future); - cass_cluster_free(cluster); cass_session_free(session); + cass_cluster_free(cluster); return 0; } diff --git a/examples/dse/date_range/date_range.c b/examples/dse/date_range/date_range.c deleted file mode 100644 index 66d913e56..000000000 --- a/examples/dse/date_range/date_range.c +++ /dev/null @@ -1,437 +0,0 @@ -/* - This is free and unencumbered software released into the public domain. - - Anyone is free to copy, modify, publish, use, compile, sell, or - distribute this software, either in source code form or as a compiled - binary, for any purpose, commercial or non-commercial, and by any - means. - - In jurisdictions that recognize copyright laws, the author or authors - of this software dedicate any and all copyright interest in the - software to the public domain. We make this dedication for the benefit - of the public at large and to the detriment of our heirs and - successors. We intend this dedication to be an overt act of - relinquishment in perpetuity of all present and future rights to this - software under copyright law. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - - For more information, please refer to -*/ - -#include -#include -#include -#include - -#include "dse.h" - -void print_error(CassFuture* future) { - const char* message; - size_t message_length; - cass_future_error_message(future, &message, &message_length); - fprintf(stderr, "Error: %.*s\n", (int)message_length, message); -} - -void precision_to_string(DseDateRangePrecision precision, char* precision_string) { - switch (precision) { - case DSE_DATE_RANGE_PRECISION_YEAR: - strcpy(precision_string, "YEAR"); - break; - case DSE_DATE_RANGE_PRECISION_MONTH: - strcpy(precision_string, "MONTH"); - break; - case DSE_DATE_RANGE_PRECISION_DAY: - strcpy(precision_string, "DAY"); - break; - case DSE_DATE_RANGE_PRECISION_HOUR: - strcpy(precision_string, "HOUR"); - break; - case DSE_DATE_RANGE_PRECISION_MINUTE: - strcpy(precision_string, "MINUTE"); - break; - case DSE_DATE_RANGE_PRECISION_SECOND: - strcpy(precision_string, "SECOND"); - break; - case DSE_DATE_RANGE_PRECISION_MILLISECOND: - strcpy(precision_string, "MILLISECOND"); - break; - default: - strcpy(precision_string, "UNKNOWN"); - } -} - -void time_to_string(cass_int64_t time_int, char* time_string) { - /* time_int is ms-precision. */ - time_t time_secs = (time_t)time_int / 1000; - strftime(time_string, 20, "%Y-%m-%d %H:%M:%S", gmtime(&time_secs)); - sprintf(time_string + 19, ".%03d", (int)(time_int % 1000)); -} - -void print_range(const DseDateRange* range) { - char from_precision_string[20], to_precision_string[20], from_time_string[30], to_time_string[30]; - - if (range->is_single_date) { - if (dse_date_range_bound_is_unbounded(range->lower_bound)) { - printf("*\n"); - } else { - precision_to_string(range->lower_bound.precision, from_precision_string); - time_to_string(range->lower_bound.time_ms, from_time_string); - printf("%s(%s)\n", from_time_string, from_precision_string); - } - } else if (dse_date_range_bound_is_unbounded(range->lower_bound) && - dse_date_range_bound_is_unbounded(range->upper_bound)) { - printf("* TO *\n"); - } else if (dse_date_range_bound_is_unbounded(range->upper_bound)) { - precision_to_string(range->lower_bound.precision, from_precision_string); - time_to_string(range->lower_bound.time_ms, from_time_string); - printf("%s(%s) TO *\n", from_time_string, from_precision_string); - } else if (dse_date_range_bound_is_unbounded(range->lower_bound)) { - precision_to_string(range->upper_bound.precision, to_precision_string); - time_to_string(range->upper_bound.time_ms, to_time_string); - printf("* TO %s(%s)\n", to_time_string, to_precision_string); - } else { - precision_to_string(range->lower_bound.precision, from_precision_string); - time_to_string(range->lower_bound.time_ms, from_time_string); - precision_to_string(range->upper_bound.precision, to_precision_string); - time_to_string(range->upper_bound.time_ms, to_time_string); - printf("%s(%s) TO %s(%s)\n", from_time_string, from_precision_string, to_time_string, - to_precision_string); - } -} - -CassCluster* create_cluster(const char* hosts) { - CassCluster* cluster = cass_cluster_new(); - cass_cluster_set_contact_points(cluster, hosts); - cass_cluster_set_dse_plaintext_authenticator(cluster, "cassandra", "cassandra"); - return cluster; -} - -CassError connect_session(CassSession* session, const CassCluster* cluster) { - CassError rc = CASS_OK; - CassFuture* future = cass_session_connect(session, cluster); - - rc = cass_future_error_code(future); - if (rc != CASS_OK) { - print_error(future); - } - cass_future_free(future); - - return rc; -} - -CassError execute_query(CassSession* session, const char* query) { - CassError rc = CASS_OK; - CassFuture* future = NULL; - CassStatement* statement = cass_statement_new(query, 0); - - future = cass_session_execute(session, statement); - - rc = cass_future_error_code(future); - if (rc != CASS_OK) { - print_error(future); - } - - cass_future_free(future); - cass_statement_free(statement); - - return rc; -} - -CassError insert_into_table(CassSession* session, const char* key, const DseDateRange* range) { - CassError rc = CASS_OK; - CassStatement* statement = NULL; - CassFuture* future = NULL; - const char* query = "INSERT INTO examples.dr (key, value) VALUES (?, ?);"; - - statement = cass_statement_new(query, 2); - - cass_statement_bind_string(statement, 0, key); - cass_statement_bind_dse_date_range(statement, 1, range); - - future = cass_session_execute(session, statement); - - rc = cass_future_error_code(future); - if (rc != CASS_OK) { - print_error(future); - } - - cass_future_free(future); - cass_statement_free(statement); - - return rc; -} - -CassError select_from_table(CassSession* session) { - CassError rc = CASS_OK; - CassStatement* statement = NULL; - CassFuture* future = NULL; - const char* query = "SELECT * FROM examples.dr"; - - statement = cass_statement_new(query, 0); - - future = cass_session_execute(session, statement); - - rc = cass_future_error_code(future); - if (rc != CASS_OK) { - print_error(future); - } else { - const CassResult* result = cass_future_get_result(future); - CassIterator* iterator = cass_iterator_from_result(result); - - while (cass_iterator_next(iterator)) { - const char* row_key; - size_t row_key_length; - const CassRow* row = cass_iterator_get_row(iterator); - int rc = 0; - DseDateRange range; - - if ((rc = cass_value_get_string(cass_row_get_column(row, 0), &row_key, &row_key_length)) == - CASS_OK) { - printf("%.*s\t", (int)row_key_length, row_key); - } else { - printf("got error: %d\n", rc); - } - - if ((rc = cass_value_get_dse_date_range(cass_row_get_column(row, 1), &range)) == CASS_OK) { - print_range(&range); - } else { - printf("got error: %d\n", rc); - } - } - - cass_result_free(result); - cass_iterator_free(iterator); - } - - cass_future_free(future); - cass_statement_free(statement); - - return rc; -} - -CassError insert_into_collections(CassSession* session, const char* key, const DseDateRange* range1, - const DseDateRange* range2) { - CassError rc = CASS_OK; - CassStatement* statement = NULL; - CassFuture* future = NULL; - CassCollection* collection = NULL; - CassTuple* tuple = NULL; - const CassSchemaMeta* schema_meta = NULL; - const CassKeyspaceMeta* keyspace_meta = NULL; - const CassDataType* udt_type = NULL; - CassUserType* udt = NULL; - - const char* query = - "INSERT INTO examples.drcoll (key, coll_value, tuple_value, udt_value) VALUES (?, ?, ?, ?);"; - statement = cass_statement_new(query, 4); - - cass_statement_bind_string(statement, 0, key); - - /* Set up a collection. */ - collection = cass_collection_new(CASS_COLLECTION_TYPE_SET, 2); - cass_collection_append_dse_date_range(collection, range1); - cass_collection_append_dse_date_range(collection, range2); - - cass_statement_bind_collection(statement, 1, collection); - cass_collection_free(collection); - - /* Set up a tuple. */ - tuple = cass_tuple_new(2); - cass_tuple_set_dse_date_range(tuple, 0, range2); - cass_tuple_set_dse_date_range(tuple, 1, range1); - - cass_statement_bind_tuple(statement, 2, tuple); - cass_tuple_free(tuple); - - /* Set up the udt. */ - schema_meta = cass_session_get_schema_meta(session); - keyspace_meta = cass_schema_meta_keyspace_by_name(schema_meta, "examples"); - udt_type = cass_keyspace_meta_user_type_by_name(keyspace_meta, "dr_user_type"); - udt = cass_user_type_new_from_data_type(udt_type); - cass_user_type_set_dse_date_range_by_name(udt, "sub", range1); - - cass_statement_bind_user_type(statement, 3, udt); - cass_user_type_free(udt); - cass_schema_meta_free(schema_meta); - - /* Insert the row. */ - future = cass_session_execute(session, statement); - - rc = cass_future_error_code(future); - if (rc != CASS_OK) { - print_error(future); - } - - cass_future_free(future); - cass_statement_free(statement); - - return rc; -} - -CassError select_from_collections(CassSession* session, const char* key) { - CassError rc = CASS_OK; - CassStatement* statement = NULL; - CassFuture* future = NULL; - const char* query = - "SELECT coll_value, tuple_value, udt_value FROM examples.drcoll WHERE key = ?"; - - statement = cass_statement_new(query, 1); - cass_statement_bind_string(statement, 0, key); - - future = cass_session_execute(session, statement); - - rc = cass_future_error_code(future); - if (rc != CASS_OK) { - print_error(future); - } else { - const CassResult* result = cass_future_get_result(future); - CassIterator* iterator = cass_iterator_from_result(result); - - if (cass_iterator_next(iterator)) { - const CassValue* value = NULL; - const CassRow* row = cass_iterator_get_row(iterator); - CassIterator* items_iterator = NULL; - - /* Get coll_value and print it out. */ - value = cass_row_get_column(row, 0); - items_iterator = cass_iterator_from_collection(value); - printf("coll_value:\n"); - while (cass_iterator_next(items_iterator)) { - DseDateRange range; - cass_value_get_dse_date_range(cass_iterator_get_value(items_iterator), &range); - printf(" "); - print_range(&range); - } - cass_iterator_free(items_iterator); - - /* Get tuple_value and print it out. */ - value = cass_row_get_column(row, 1); - items_iterator = cass_iterator_from_tuple(value); - printf("tuple_value:\n"); - while (cass_iterator_next(items_iterator)) { - DseDateRange range; - cass_value_get_dse_date_range(cass_iterator_get_value(items_iterator), &range); - printf(" "); - print_range(&range); - } - cass_iterator_free(items_iterator); - - /* Get udt_value */ - value = cass_row_get_column(row, 2); - items_iterator = cass_iterator_fields_from_user_type(value); - printf("udt_value:\n"); - while (items_iterator != NULL && cass_iterator_next(items_iterator)) { - const char* field_name; - size_t field_name_length; - const CassValue* field_value = NULL; - DseDateRange range; - cass_iterator_get_user_type_field_name(items_iterator, &field_name, &field_name_length); - field_value = cass_iterator_get_user_type_field_value(items_iterator); - printf(" %.*s ", (int)field_name_length, field_name); - cass_value_get_dse_date_range(field_value, &range); - print_range(&range); - } - cass_iterator_free(items_iterator); - - printf("\n"); - } - - cass_result_free(result); - cass_iterator_free(iterator); - } - - cass_future_free(future); - cass_statement_free(statement); - - return rc; -} - -int main(int argc, char* argv[]) { - CassCluster* cluster = NULL; - CassSession* session = cass_session_new(); - char* hosts = "127.0.0.1"; - time_t now = time(NULL); - DseDateRange range, range2; - - if (argc > 1) { - hosts = argv[1]; - } - cluster = create_cluster(hosts); - - if (connect_session(session, cluster) != CASS_OK) { - cass_cluster_free(cluster); - cass_session_free(session); - return -1; - } - - execute_query(session, "CREATE KEYSPACE IF NOT EXISTS examples WITH replication = { \ - 'class': 'SimpleStrategy', 'replication_factor': '1' };"); - - execute_query(session, "CREATE TABLE IF NOT EXISTS examples.dr (key text PRIMARY KEY, \ - value 'DateRangeType');"); - - execute_query(session, "CREATE TYPE IF NOT EXISTS examples.dr_user_type (sub 'DateRangeType')"); - - execute_query(session, "CREATE TABLE IF NOT EXISTS examples.drcoll (key text PRIMARY KEY, \ - coll_value set<'DateRangeType'>, \ - tuple_value tuple<'DateRangeType', 'DateRangeType'>, \ - udt_value dr_user_type)"); - - /* Insert a different flavors of date ranges into examples.dr. */ - insert_into_table(session, "open range", - dse_date_range_init(&range, dse_date_range_bound_unbounded(), - dse_date_range_bound_unbounded())); - insert_into_table(session, "open value", - dse_date_range_init_single_date(&range, dse_date_range_bound_unbounded())); - insert_into_table(session, "single value", - dse_date_range_init_single_date( - &range, dse_date_range_bound_init(DSE_DATE_RANGE_PRECISION_MONTH, - ((cass_int64_t)now) * 1000))); - insert_into_table(session, "open high, day", - dse_date_range_init(&range, - dse_date_range_bound_init(DSE_DATE_RANGE_PRECISION_DAY, - ((cass_int64_t)now) * 1000), - dse_date_range_bound_unbounded())); - insert_into_table( - session, "open low, ms", - dse_date_range_init(&range, dse_date_range_bound_unbounded(), - dse_date_range_bound_init(DSE_DATE_RANGE_PRECISION_MILLISECOND, - ((cass_int64_t)now) * 1000))); - - /* Closed range from 1/2/1970 to now (with some millis tacked on to show that millis are handled - * properly). */ - insert_into_table(session, "closed range", - dse_date_range_init( - &range, dse_date_range_bound_init(DSE_DATE_RANGE_PRECISION_YEAR, 86400000), - dse_date_range_bound_init(DSE_DATE_RANGE_PRECISION_MILLISECOND, - ((cass_int64_t)now) * 1000 + 987))); - - /* Now query examples.dr and print out the results. */ - printf("examples.dr:\n"); - select_from_table(session); - - /* Insert a row in the collection table. */ - - dse_date_range_init(&range, dse_date_range_bound_init(DSE_DATE_RANGE_PRECISION_DAY, 86400000), - dse_date_range_bound_init(DSE_DATE_RANGE_PRECISION_MILLISECOND, - ((cass_int64_t)now) * 1000 + 123)); - dse_date_range_init_single_date(&range2, dse_date_range_bound_unbounded()); - - insert_into_collections(session, "key", &range, &range2); - - /* Query the collection table and print out the results. */ - printf("\n\nexamples.drcoll:\n"); - select_from_collections(session, "key"); - - cass_cluster_free(cluster); - cass_session_free(session); - - return 0; -} diff --git a/examples/dse/geotypes/.gitignore b/examples/dse/geotypes/.gitignore deleted file mode 100644 index afc6ba2fe..000000000 --- a/examples/dse/geotypes/.gitignore +++ /dev/null @@ -1 +0,0 @@ -geotypes diff --git a/examples/dse/geotypes/CMakeLists.txt b/examples/dse/geotypes/CMakeLists.txt deleted file mode 100644 index ee0fab7b2..000000000 --- a/examples/dse/geotypes/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -cmake_minimum_required(VERSION 3.15) - -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ".") -set(PROJECT_EXAMPLE_NAME geotypes) - -file(GLOB EXAMPLE_SRC_FILES *.c) -include_directories(${INCLUDES}) -add_executable(${PROJECT_EXAMPLE_NAME} ${EXAMPLE_SRC_FILES}) -target_link_libraries(${PROJECT_EXAMPLE_NAME} ${PROJECT_LIB_NAME_TARGET} ${DSE_LIBS}) -add_dependencies(${PROJECT_EXAMPLE_NAME} ${PROJECT_LIB_NAME_TARGET}) - -set_target_properties(${PROJECT_EXAMPLE_NAME} PROPERTIES FOLDER "Examples" - COMPILE_FLAGS "${EXAMPLE_CMAKE_C_FLAGS}") diff --git a/examples/dse/geotypes/geotypes.c b/examples/dse/geotypes/geotypes.c deleted file mode 100644 index 4914041d4..000000000 --- a/examples/dse/geotypes/geotypes.c +++ /dev/null @@ -1,884 +0,0 @@ -/* - This is free and unencumbered software released into the public domain. - - Anyone is free to copy, modify, publish, use, compile, sell, or - distribute this software, either in source code form or as a compiled - binary, for any purpose, commercial or non-commercial, and by any - means. - - In jurisdictions that recognize copyright laws, the author or authors - of this software dedicate any and all copyright interest in the - software to the public domain. We make this dedication for the benefit - of the public at large and to the detriment of our heirs and - successors. We intend this dedication to be an overt act of - relinquishment in perpetuity of all present and future rights to this - software under copyright law. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - - For more information, please refer to -*/ - -#include - -#include -#include -#include - -CassDataType* point_user_type; -CassDataType* line_string_user_type; -CassDataType* polygon_user_type; - -void print_error(CassFuture* future) { - const char* message; - size_t message_length; - cass_future_error_message(future, &message, &message_length); - fprintf(stderr, "Error: %.*s\n", (int)message_length, message); -} - -CassCluster* create_cluster(const char* hosts) { - CassCluster* cluster = cass_cluster_new(); - cass_cluster_set_contact_points(cluster, hosts); - return cluster; -} - -CassError connect_session(CassSession* session, const CassCluster* cluster) { - CassError rc = CASS_OK; - CassFuture* future = cass_session_connect(session, cluster); - - cass_future_wait(future); - rc = cass_future_error_code(future); - if (rc != CASS_OK) { - print_error(future); - } - cass_future_free(future); - - return rc; -} - -CassError execute_query(CassSession* session, const char* query) { - CassError rc = CASS_OK; - CassFuture* future = NULL; - CassStatement* statement = cass_statement_new(query, 0); - - future = cass_session_execute(session, statement); - cass_future_wait(future); - - rc = cass_future_error_code(future); - if (rc != CASS_OK) { - print_error(future); - } - - cass_future_free(future); - cass_statement_free(statement); - - return rc; -} - -void print_point(cass_double_t x, cass_double_t y) { printf("POINT(%.1f %.1f)", x, y); } - -void insert_point(CassSession* session, const char* key, cass_double_t x, cass_double_t y) { - CassFuture* future = NULL; - CassStatement* statement = cass_statement_new("INSERT INTO examples.geotypes " - "(key, point) VALUES (?, ?)", - 2); - - cass_statement_bind_string(statement, 0, key); - cass_statement_bind_dse_point(statement, 1, x, y); - - future = cass_session_execute(session, statement); - - if (cass_future_error_code(future) != CASS_OK) { - print_error(future); - } - - cass_future_free(future); - cass_statement_free(statement); -} - -void select_point(CassSession* session, const char* key) { - CassFuture* future = NULL; - CassStatement* statement = - cass_statement_new("SELECT point FROM examples.geotypes WHERE key = ?", 1); - - cass_statement_bind_string(statement, 0, key); - - future = cass_session_execute(session, statement); - - if (cass_future_error_code(future) == CASS_OK) { - cass_double_t x = 0.0, y = 0.0; - const CassResult* result = cass_future_get_result(future); - if (result && cass_result_row_count(result) > 0) { - const CassRow* row = cass_result_first_row(result); - const CassValue* value = cass_row_get_column_by_name(row, "point"); - - cass_value_get_dse_point(value, &x, &y); - printf("%s: ", key); - print_point(x, y); - printf("\n"); - - cass_result_free(result); - } - } else { - print_error(future); - } - - cass_future_free(future); - cass_statement_free(statement); -} - -void insert_point_collections(CassSession* session, const char* key) { - CassFuture* future = NULL; - CassStatement* statement = - cass_statement_new("INSERT INTO examples.geotypes_collections " - "(key, point_list, point_tuple, point_udt) VALUES (?, ?, ?, ?)", - 4); - - cass_statement_bind_string(statement, 0, key); - - { /* Bind point list */ - CassCollection* point_list = cass_collection_new(CASS_COLLECTION_TYPE_LIST, 2); - cass_collection_append_dse_point(point_list, 1.0, 2.0); - cass_collection_append_dse_point(point_list, 2.0, 3.0); - cass_statement_bind_collection(statement, 1, point_list); - cass_collection_free(point_list); - } - - { /* Bind point tuple */ - CassTuple* point_tuple = cass_tuple_new(2); - cass_tuple_set_dse_point(point_tuple, 0, 3.0, 4.0); - cass_tuple_set_dse_point(point_tuple, 1, 4.0, 5.0); - cass_statement_bind_tuple(statement, 2, point_tuple); - cass_tuple_free(point_tuple); - } - - { /* Bind point UDT */ - CassUserType* point_udt = cass_user_type_new_from_data_type(point_user_type); - - /* Set using a name */ - cass_user_type_set_dse_point_by_name(point_udt, "point1", 5.0, 6.0); - - /* Set using an index */ - cass_user_type_set_dse_point(point_udt, 1, 6.0, 7.0); - - cass_statement_bind_user_type(statement, 3, point_udt); - cass_user_type_free(point_udt); - } - - future = cass_session_execute(session, statement); - - if (cass_future_error_code(future) != CASS_OK) { - print_error(future); - } - - cass_future_free(future); - cass_statement_free(statement); -} - -void select_point_collections(CassSession* session, const char* key) { - CassFuture* future = NULL; - CassStatement* statement = cass_statement_new("SELECT point_list, point_tuple, point_udt " - "FROM examples.geotypes_collections WHERE key = ?", - 1); - - cass_statement_bind_string(statement, 0, key); - - future = cass_session_execute(session, statement); - - if (cass_future_error_code(future) == CASS_OK) { - const CassResult* result = cass_future_get_result(future); - if (result && cass_result_row_count(result) > 0) { - const CassRow* row = cass_result_first_row(result); - - { /* Get point list */ - int i = 0; - const CassValue* point_list = cass_row_get_column_by_name(row, "point_list"); - CassIterator* iterator = cass_iterator_from_collection(point_list); - printf("point_list: ["); - while (cass_iterator_next(iterator)) { - cass_double_t x, y; - const CassValue* point = cass_iterator_get_value(iterator); - cass_value_get_dse_point(point, &x, &y); - if (i++ > 0) printf(", "); - print_point(x, y); - } - printf("]\n"); - cass_iterator_free(iterator); - } - - { /* Get point tuple */ - int i = 0; - const CassValue* point_tuple = cass_row_get_column_by_name(row, "point_tuple"); - CassIterator* iterator = cass_iterator_from_tuple(point_tuple); - printf("point_tuple: ("); - while (cass_iterator_next(iterator)) { - cass_double_t x, y; - const CassValue* point = cass_iterator_get_value(iterator); - cass_value_get_dse_point(point, &x, &y); - if (i++ > 0) printf(", "); - print_point(x, y); - } - printf(")\n"); - cass_iterator_free(iterator); - } - - { /* Get point UDT */ - int i = 0; - const CassValue* point_udt = cass_row_get_column_by_name(row, "point_udt"); - CassIterator* iterator = cass_iterator_fields_from_user_type(point_udt); - printf("point_udt: {"); - while (cass_iterator_next(iterator)) { - const char* field_name; - size_t field_name_length; - cass_double_t x, y; - const CassValue* point = cass_iterator_get_user_type_field_value(iterator); - cass_iterator_get_user_type_field_name(iterator, &field_name, &field_name_length); - cass_value_get_dse_point(point, &x, &y); - if (i++ > 0) printf(", "); - printf("%.*s: ", (int)field_name_length, field_name); - print_point(x, y); - } - printf("}\n"); - } - - cass_result_free(result); - } - } else { - print_error(future); - } - - cass_future_free(future); - cass_statement_free(statement); -} - -void print_line_string(DseLineStringIterator* iterator) { - cass_int32_t i, num_points = dse_line_string_iterator_num_points(iterator); - printf("LINESTRING("); - for (i = 0; i < num_points; ++i) { - cass_double_t x, y; - dse_line_string_iterator_next_point(iterator, &x, &y); - if (i > 0) printf(", "); - printf("%.1f %.1f", x, y); - } - printf(")"); -} - -void insert_line_string(CassSession* session, const char* key, int num_points, ...) { - int i; - va_list args; - CassFuture* future = NULL; - CassStatement* statement = cass_statement_new("INSERT INTO examples.geotypes " - "(key, linestring) VALUES (?, ?)", - 2); - DseLineString* line_string = dse_line_string_new(); - - dse_line_string_reserve(line_string, num_points); - - va_start(args, num_points); - for (i = 0; i < num_points; ++i) { - cass_double_t x = va_arg(args, cass_double_t); - cass_double_t y = va_arg(args, cass_double_t); - dse_line_string_add_point(line_string, x, y); - } - va_end(args); - - dse_line_string_finish(line_string); - - cass_statement_bind_string(statement, 0, key); - cass_statement_bind_dse_line_string(statement, 1, line_string); - - future = cass_session_execute(session, statement); - - if (cass_future_error_code(future) != CASS_OK) { - print_error(future); - } - - cass_future_free(future); - dse_line_string_free(line_string); - cass_statement_free(statement); -} - -void select_line_string(CassSession* session, const char* key) { - CassFuture* future = NULL; - CassStatement* statement = - cass_statement_new("SELECT linestring FROM examples.geotypes WHERE key = ?", 1); - - cass_statement_bind_string(statement, 0, key); - - future = cass_session_execute(session, statement); - - if (cass_future_error_code(future) == CASS_OK) { - const CassResult* result = cass_future_get_result(future); - if (result && cass_result_row_count(result) > 0) { - const CassRow* row = cass_result_first_row(result); - const CassValue* value = cass_row_get_column_by_name(row, "linestring"); - - DseLineStringIterator* iterator = dse_line_string_iterator_new(); - - dse_line_string_iterator_reset(iterator, value); - - printf("%s: ", key); - print_line_string(iterator); - printf(")\n"); - - dse_line_string_iterator_free(iterator); - cass_result_free(result); - } - } else { - print_error(future); - } - - cass_future_free(future); - cass_statement_free(statement); -} - -void insert_line_string_collections(CassSession* session, const char* key) { - CassFuture* future = NULL; - CassStatement* statement = cass_statement_new( - "INSERT INTO examples.geotypes_collections " - "(key, linestring_set, linestring_tuple, linestring_udt) VALUES (?, ?, ?, ?)", - 4); - DseLineString* line_string = dse_line_string_new(); - - cass_statement_bind_string(statement, 0, key); - - { /* Bind line string set */ - CassCollection* line_string_set = cass_collection_new(CASS_COLLECTION_TYPE_SET, 2); - - dse_line_string_reset(line_string); - dse_line_string_add_point(line_string, 0.0, 0.0); - dse_line_string_add_point(line_string, 1.0, 1.0); - dse_line_string_finish(line_string); - cass_collection_append_dse_line_string(line_string_set, line_string); - - dse_line_string_reset(line_string); - dse_line_string_add_point(line_string, 1.0, 1.0); - dse_line_string_add_point(line_string, 2.0, 2.0); - dse_line_string_finish(line_string); - cass_collection_append_dse_line_string(line_string_set, line_string); - - cass_statement_bind_collection(statement, 1, line_string_set); - cass_collection_free(line_string_set); - } - - { /* Bind line string tuple */ - CassTuple* line_string_tuple = cass_tuple_new(2); - - dse_line_string_reset(line_string); - dse_line_string_add_point(line_string, 1.0, 1.0); - dse_line_string_add_point(line_string, 2.0, 2.0); - dse_line_string_add_point(line_string, 3.0, 3.0); - dse_line_string_finish(line_string); - cass_tuple_set_dse_line_string(line_string_tuple, 0, line_string); - - dse_line_string_reset(line_string); - dse_line_string_add_point(line_string, 4.0, 4.0); - dse_line_string_add_point(line_string, 5.0, 5.0); - dse_line_string_add_point(line_string, 6.0, 6.0); - dse_line_string_finish(line_string); - cass_tuple_set_dse_line_string(line_string_tuple, 1, line_string); - - cass_statement_bind_tuple(statement, 2, line_string_tuple); - cass_tuple_free(line_string_tuple); - } - - { /* Bind line string UDT */ - CassUserType* line_string_udt = cass_user_type_new_from_data_type(line_string_user_type); - - /* Set using a name */ - dse_line_string_reset(line_string); - dse_line_string_add_point(line_string, 0.0, 0.0); - dse_line_string_add_point(line_string, 0.0, 1.0); - dse_line_string_add_point(line_string, 1.0, 2.0); - dse_line_string_add_point(line_string, 2.0, 3.0); - dse_line_string_finish(line_string); - cass_user_type_set_dse_line_string_by_name(line_string_udt, "linestring1", line_string); - - /* Set using an index */ - dse_line_string_reset(line_string); - dse_line_string_add_point(line_string, 2.0, 3.0); - dse_line_string_add_point(line_string, 3.0, 5.0); - dse_line_string_add_point(line_string, 5.0, 7.0); - dse_line_string_add_point(line_string, 7.0, 9.0); - dse_line_string_finish(line_string); - cass_user_type_set_dse_line_string(line_string_udt, 1, line_string); - - cass_statement_bind_user_type(statement, 3, line_string_udt); - cass_user_type_free(line_string_udt); - } - - future = cass_session_execute(session, statement); - - if (cass_future_error_code(future) != CASS_OK) { - print_error(future); - } - - dse_line_string_free(line_string); - cass_future_free(future); - cass_statement_free(statement); -} - -void select_line_string_collections(CassSession* session, const char* key) { - CassFuture* future = NULL; - CassStatement* statement = - cass_statement_new("SELECT linestring_set, linestring_tuple, linestring_udt " - "FROM examples.geotypes_collections WHERE key = ?", - 1); - DseLineStringIterator* line_string_iterator = dse_line_string_iterator_new(); - - cass_statement_bind_string(statement, 0, key); - - future = cass_session_execute(session, statement); - - if (cass_future_error_code(future) == CASS_OK) { - const CassResult* result = cass_future_get_result(future); - if (result && cass_result_row_count(result) > 0) { - const CassRow* row = cass_result_first_row(result); - - { /* Get line string set */ - int i = 0; - const CassValue* line_string_set = cass_row_get_column_by_name(row, "linestring_set"); - CassIterator* iterator = cass_iterator_from_collection(line_string_set); - printf("linestring_set: ["); - while (cass_iterator_next(iterator)) { - const CassValue* line_string = cass_iterator_get_value(iterator); - dse_line_string_iterator_reset(line_string_iterator, line_string); - if (i++ > 0) printf(", "); - print_line_string(line_string_iterator); - } - printf("]\n"); - cass_iterator_free(iterator); - } - - { /* Get line string tuple */ - int i = 0; - const CassValue* line_string_tuple = cass_row_get_column_by_name(row, "linestring_tuple"); - CassIterator* iterator = cass_iterator_from_tuple(line_string_tuple); - printf("linestring_tuple: ("); - while (cass_iterator_next(iterator)) { - const CassValue* line_string = cass_iterator_get_value(iterator); - dse_line_string_iterator_reset(line_string_iterator, line_string); - if (i++ > 0) printf(", "); - print_line_string(line_string_iterator); - } - printf(")\n"); - cass_iterator_free(iterator); - } - - { /* Get line string UDT */ - int i = 0; - const CassValue* line_string_udt = cass_row_get_column_by_name(row, "linestring_udt"); - CassIterator* iterator = cass_iterator_fields_from_user_type(line_string_udt); - printf("linestring_udt: {"); - while (cass_iterator_next(iterator)) { - const char* field_name; - size_t field_name_length; - const CassValue* line_string = cass_iterator_get_user_type_field_value(iterator); - dse_line_string_iterator_reset(line_string_iterator, line_string); - cass_iterator_get_user_type_field_name(iterator, &field_name, &field_name_length); - if (i++ > 0) printf(", "); - printf("%.*s: ", (int)field_name_length, field_name); - print_line_string(line_string_iterator); - } - printf("}\n"); - } - - cass_result_free(result); - } - } else { - print_error(future); - } - - dse_line_string_iterator_free(line_string_iterator); - cass_future_free(future); - cass_statement_free(statement); -} - -void print_polygon(DsePolygonIterator* iterator) { - cass_int32_t i, num_rings = dse_polygon_iterator_num_rings(iterator); - printf("POLYGON("); - for (i = 0; i < num_rings; ++i) { - cass_uint32_t j, num_points = 0; - dse_polygon_iterator_next_num_points(iterator, &num_points); - printf("("); - for (j = 0; j < num_points; ++j) { - cass_double_t x = 0.0, y; - dse_polygon_iterator_next_point(iterator, &x, &y); - if (j > 0) printf(", "); - printf("%.1f %.1f", x, y); - } - printf(")"); - } - printf(")"); -} - -void insert_polygon(CassSession* session, const char* key, int num_rings, ...) { - int i, j; - va_list args; - CassFuture* future = NULL; - CassStatement* statement = cass_statement_new("INSERT INTO examples.geotypes " - "(key, polygon) VALUES (?, ?)", - 2); - - DsePolygon* polygon = dse_polygon_new(); - - va_start(args, num_rings); - for (i = 0; i < num_rings; ++i) { - int num_points = va_arg(args, int); - dse_polygon_start_ring(polygon); - for (j = 0; j < num_points; ++j) { - cass_double_t x = va_arg(args, cass_double_t); - cass_double_t y = va_arg(args, cass_double_t); - dse_polygon_add_point(polygon, x, y); - } - } - va_end(args); - - dse_polygon_finish(polygon); - - cass_statement_bind_string(statement, 0, key); - cass_statement_bind_dse_polygon(statement, 1, polygon); - - future = cass_session_execute(session, statement); - - if (cass_future_error_code(future) != CASS_OK) { - print_error(future); - } - - cass_future_free(future); - dse_polygon_free(polygon); - cass_statement_free(statement); -} - -void select_polygon(CassSession* session, const char* key) { - CassFuture* future = NULL; - CassStatement* statement = - cass_statement_new("SELECT polygon FROM examples.geotypes WHERE key = ?", 1); - - cass_statement_bind_string(statement, 0, key); - - future = cass_session_execute(session, statement); - - if (cass_future_error_code(future) == CASS_OK) { - const CassResult* result = cass_future_get_result(future); - if (result && cass_result_row_count(result) > 0) { - const CassRow* row = cass_result_first_row(result); - const CassValue* value = cass_row_get_column_by_name(row, "polygon"); - - DsePolygonIterator* iterator = dse_polygon_iterator_new(); - - dse_polygon_iterator_reset(iterator, value); - - printf("%s: ", key); - print_polygon(iterator); - printf("\n"); - - dse_polygon_iterator_free(iterator); - cass_result_free(result); - } - } else { - print_error(future); - } - - cass_future_free(future); - cass_statement_free(statement); -} - -void insert_polygon_collections(CassSession* session, const char* key) { - CassFuture* future = NULL; - CassStatement* statement = - cass_statement_new("INSERT INTO examples.geotypes_collections " - "(key, polygon_map, polygon_tuple, polygon_udt) VALUES (?, ?, ?, ?)", - 4); - DsePolygon* polygon = dse_polygon_new(); - - cass_statement_bind_string(statement, 0, key); - - { /* Bind polygon map */ - CassCollection* polygon_map = cass_collection_new(CASS_COLLECTION_TYPE_MAP, 2); - - cass_collection_append_string(polygon_map, "poly1"); - dse_polygon_reset(polygon); - dse_polygon_start_ring(polygon); - dse_polygon_add_point(polygon, 0.0, 0.0); - dse_polygon_add_point(polygon, 1.0, 0.0); - dse_polygon_add_point(polygon, 1.0, 1.0); - dse_polygon_add_point(polygon, 0.0, 0.0); - dse_polygon_finish(polygon); - cass_collection_append_dse_polygon(polygon_map, polygon); - - cass_collection_append_string(polygon_map, "poly2"); - dse_polygon_reset(polygon); - dse_polygon_start_ring(polygon); - dse_polygon_add_point(polygon, 0.0, 0.0); - dse_polygon_add_point(polygon, 1.0, 0.0); - dse_polygon_add_point(polygon, 1.0, 1.0); - dse_polygon_add_point(polygon, 0.0, 1.0); - dse_polygon_add_point(polygon, 0.0, 0.0); - dse_polygon_finish(polygon); - cass_collection_append_dse_polygon(polygon_map, polygon); - - cass_statement_bind_collection(statement, 1, polygon_map); - cass_collection_free(polygon_map); - } - - { /* Bind polygon tuple */ - CassTuple* polygon_tuple = cass_tuple_new(2); - - dse_polygon_reset(polygon); - dse_polygon_start_ring(polygon); - dse_polygon_add_point(polygon, 0.0, 0.0); - dse_polygon_add_point(polygon, 2.0, 0.0); - dse_polygon_add_point(polygon, 2.0, 2.0); - dse_polygon_add_point(polygon, 0.0, 0.0); - dse_polygon_finish(polygon); - cass_tuple_set_dse_polygon(polygon_tuple, 0, polygon); - - dse_polygon_reset(polygon); - dse_polygon_start_ring(polygon); - dse_polygon_add_point(polygon, 0.0, 0.0); - dse_polygon_add_point(polygon, 2.0, 0.0); - dse_polygon_add_point(polygon, 2.0, 2.0); - dse_polygon_add_point(polygon, 0.0, 2.0); - dse_polygon_add_point(polygon, 0.0, 0.0); - dse_polygon_finish(polygon); - cass_tuple_set_dse_polygon(polygon_tuple, 1, polygon); - - cass_statement_bind_tuple(statement, 2, polygon_tuple); - cass_tuple_free(polygon_tuple); - } - - { /* Bind polygon UDT */ - CassUserType* polygon_udt = cass_user_type_new_from_data_type(polygon_user_type); - - /* Set using a name */ - dse_polygon_reset(polygon); - dse_polygon_start_ring(polygon); - dse_polygon_add_point(polygon, 0.0, 0.0); - dse_polygon_add_point(polygon, 3.0, 0.0); - dse_polygon_add_point(polygon, 3.0, 3.0); - dse_polygon_add_point(polygon, 0.0, 3.0); - dse_polygon_add_point(polygon, 0.0, 0.0); - dse_polygon_finish(polygon); - cass_user_type_set_dse_polygon_by_name(polygon_udt, "polygon1", polygon); - - /* Set using a index */ - dse_polygon_reset(polygon); - dse_polygon_start_ring(polygon); - dse_polygon_add_point(polygon, 0.0, 0.0); - dse_polygon_add_point(polygon, 4.0, 0.0); - dse_polygon_add_point(polygon, 4.0, 4.0); - dse_polygon_add_point(polygon, 0.0, 4.0); - dse_polygon_add_point(polygon, 0.0, 0.0); - dse_polygon_finish(polygon); - cass_user_type_set_dse_polygon(polygon_udt, 1, polygon); - - cass_statement_bind_user_type(statement, 3, polygon_udt); - cass_user_type_free(polygon_udt); - } - - future = cass_session_execute(session, statement); - - if (cass_future_error_code(future) != CASS_OK) { - print_error(future); - } - - dse_polygon_free(polygon); - cass_future_free(future); - cass_statement_free(statement); -} - -void select_polygon_collections(CassSession* session, const char* key) { - CassFuture* future = NULL; - CassStatement* statement = cass_statement_new("SELECT polygon_map, polygon_tuple, polygon_udt " - "FROM examples.geotypes_collections WHERE key = ?", - 1); - DsePolygonIterator* polygon_iterator = dse_polygon_iterator_new(); - - cass_statement_bind_string(statement, 0, key); - - future = cass_session_execute(session, statement); - - if (cass_future_error_code(future) == CASS_OK) { - const CassResult* result = cass_future_get_result(future); - if (result && cass_result_row_count(result) > 0) { - const CassRow* row = cass_result_first_row(result); - - { /* Get polygon map */ - int i = 0; - const CassValue* polygon_list = cass_row_get_column_by_name(row, "polygon_map"); - CassIterator* iterator = cass_iterator_from_map(polygon_list); - printf("polygon_map: {"); - while (cass_iterator_next(iterator)) { - const char* map_name; - size_t map_name_length; - const CassValue* name = cass_iterator_get_map_key(iterator); - const CassValue* polygon = cass_iterator_get_map_value(iterator); - cass_value_get_string(name, &map_name, &map_name_length); - dse_polygon_iterator_reset(polygon_iterator, polygon); - if (i++ > 0) printf(", "); - printf("%.*s: ", (int)map_name_length, map_name); - print_polygon(polygon_iterator); - } - printf("}\n"); - cass_iterator_free(iterator); - } - - { /* Get polygon tuple */ - int i = 0; - const CassValue* polygon_tuple = cass_row_get_column_by_name(row, "polygon_tuple"); - CassIterator* iterator = cass_iterator_from_tuple(polygon_tuple); - printf("polygon_tuple: ("); - while (cass_iterator_next(iterator)) { - const CassValue* polygon = cass_iterator_get_value(iterator); - dse_polygon_iterator_reset(polygon_iterator, polygon); - if (i++ > 0) printf(", "); - print_polygon(polygon_iterator); - } - printf(")\n"); - cass_iterator_free(iterator); - } - - { /* Get polygon UDT */ - int i = 0; - const CassValue* polygon_udt = cass_row_get_column_by_name(row, "polygon_udt"); - CassIterator* iterator = cass_iterator_fields_from_user_type(polygon_udt); - printf("polygon_udt: {"); - while (cass_iterator_next(iterator)) { - const char* field_name; - size_t field_name_length; - const CassValue* polygon = cass_iterator_get_user_type_field_value(iterator); - dse_polygon_iterator_reset(polygon_iterator, polygon); - cass_iterator_get_user_type_field_name(iterator, &field_name, &field_name_length); - if (i++ > 0) printf(", "); - printf("%.*s: ", (int)field_name_length, field_name); - print_polygon(polygon_iterator); - } - printf("}\n"); - } - - cass_result_free(result); - } - } else { - print_error(future); - } - - dse_polygon_iterator_free(polygon_iterator); - cass_future_free(future); - cass_statement_free(statement); -} - -int main(int argc, char* argv[]) { - CassCluster* cluster = NULL; - CassSession* session = cass_session_new(); - char* hosts = "127.0.0.1"; - if (argc > 1) { - hosts = argv[1]; - } - cluster = create_cluster(hosts); - - if (connect_session(session, cluster) != CASS_OK) { - cass_cluster_free(cluster); - cass_session_free(session); - return -1; - } - - execute_query(session, - "CREATE KEYSPACE IF NOT EXISTS examples " - "WITH replication = { 'class': 'SimpleStrategy', 'replication_factor': '3' };"); - - execute_query(session, "CREATE TABLE IF NOT EXISTS examples.geotypes (" - "key text PRIMARY KEY, " - "point 'PointType', " - "linestring 'LineStringType', " - "polygon 'PolygonType')"); - - execute_query(session, "CREATE TYPE IF NOT EXISTS examples.point_user_type " - "(point1 'PointType', point2 'PointType')"); - - execute_query(session, "CREATE TYPE IF NOT EXISTS examples.linestring_user_type " - "(linestring1 'LineStringType', linestring2 'LineStringType')"); - - execute_query(session, "CREATE TYPE IF NOT EXISTS examples.polygon_user_type " - "(polygon1 'PolygonType', polygon2 'PolygonType')"); - - execute_query(session, "CREATE TABLE IF NOT EXISTS examples.geotypes_collections (" - "key text PRIMARY KEY, " - "point_list list<'PointType'>, " - "point_tuple tuple<'PointType', 'PointType'>, " - "point_udt point_user_type, " - "linestring_set set<'LineStringType'>, " - "linestring_tuple tuple<'LineStringType', 'LineStringType'>, " - "linestring_udt linestring_user_type, " - "polygon_map map, " - "polygon_tuple tuple<'PolygonType', 'PolygonType'>, " - "polygon_udt polygon_user_type)"); - - { /* Get geospatial user types from schema metadata */ - const CassSchemaMeta* schema = cass_session_get_schema_meta(session); - const CassKeyspaceMeta* keyspace = cass_schema_meta_keyspace_by_name(schema, "examples"); - - point_user_type = cass_data_type_new_from_existing( - cass_keyspace_meta_user_type_by_name(keyspace, "point_user_type")); - - line_string_user_type = cass_data_type_new_from_existing( - cass_keyspace_meta_user_type_by_name(keyspace, "linestring_user_type")); - - polygon_user_type = cass_data_type_new_from_existing( - cass_keyspace_meta_user_type_by_name(keyspace, "polygon_user_type")); - - cass_schema_meta_free(schema); - } - - printf("examples.geotypes (Point):\n"); - insert_point(session, "pnt1", 0.1, 0.1); - select_point(session, "pnt1"); - - printf("\nexamples.geotypes (LineString):\n"); - insert_line_string(session, "lnstr1", 0); - select_line_string(session, "lnstr1"); - - insert_line_string(session, "lnstr2", 2, 0.0, 0.0, 1.0, 1.0); - select_line_string(session, "lnstr2"); - - insert_line_string(session, "lnstr3", 3, 0.0, 0.0, 1.0, 0.0, 2.0, 0.0); - select_line_string(session, "lnstr3"); - - insert_line_string(session, "lnstr4", 4, 0.0, 0.0, 1.0, 0.0, 2.0, 0.0, 3.0, 0.0); - select_line_string(session, "lnstr4"); - - printf("\nexamples.geotypes (Polygon):\n"); - insert_polygon(session, "poly1", 0); - select_polygon(session, "poly1"); - - insert_polygon(session, "poly2", 2, 5, 35.0, 10.0, 45.0, 45.0, 15.0, 40.0, 10.0, 20.0, 35.0, 10.0, - 4, 20.0, 30.0, 35.0, 35.0, 30.0, 20.0, 20.0, 30.0); - select_polygon(session, "poly2"); - - printf("\nexamples.geotypes_collections (Point):\n"); - insert_point_collections(session, "pntcoll1"); - select_point_collections(session, "pntcoll1"); - - printf("\nexamples.geotypes_collections (LineString):\n"); - insert_line_string_collections(session, "lnstrcoll1"); - select_line_string_collections(session, "lnstrcoll1"); - - printf("\nexamples.geotypes_collections (Polygon):\n"); - insert_polygon_collections(session, "polycoll1"); - select_polygon_collections(session, "polycoll1"); - - cass_data_type_free(point_user_type); - cass_data_type_free(line_string_user_type); - cass_data_type_free(polygon_user_type); - - cass_cluster_free(cluster); - cass_session_free(session); - - return 0; -} diff --git a/examples/dse/gssapi/.gitignore b/examples/dse/gssapi/.gitignore deleted file mode 100644 index be66cd022..000000000 --- a/examples/dse/gssapi/.gitignore +++ /dev/null @@ -1 +0,0 @@ -gssapi diff --git a/examples/dse/gssapi/CMakeLists.txt b/examples/dse/gssapi/CMakeLists.txt deleted file mode 100644 index c839e2ca3..000000000 --- a/examples/dse/gssapi/CMakeLists.txt +++ /dev/null @@ -1,24 +0,0 @@ -cmake_minimum_required(VERSION 3.15) - -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ".") - -# Set up rules/commands for building gssapi example -set(PROJECT_EXAMPLE_NAME gssapi) -set(EXAMPLE_SRC_FILES gssapi.c) -include_directories(${INCLUDES}) -add_executable(${PROJECT_EXAMPLE_NAME} ${EXAMPLE_SRC_FILES}) -target_link_libraries(${PROJECT_EXAMPLE_NAME} ${PROJECT_LIB_NAME_TARGET} ${DSE_LIBS}) -add_dependencies(${PROJECT_EXAMPLE_NAME} ${PROJECT_LIB_NAME_TARGET}) - -set_target_properties(${PROJECT_EXAMPLE_NAME} PROPERTIES FOLDER "Examples" - COMPILE_FLAGS "${EXAMPLE_CMAKE_C_FLAGS}") - -# Set up rules/commands for building gssapi_proxy example -set(PROJECT_EXAMPLE_NAME gssapi_proxy) -set(EXAMPLE_SRC_FILES gssapi_proxy.c) -add_executable(${PROJECT_EXAMPLE_NAME} ${EXAMPLE_SRC_FILES}) -target_link_libraries(${PROJECT_EXAMPLE_NAME} ${PROJECT_LIB_NAME_TARGET} ${DSE_LIBS}) -add_dependencies(${PROJECT_EXAMPLE_NAME} ${PROJECT_LIB_NAME_TARGET}) - -set_target_properties(${PROJECT_EXAMPLE_NAME} PROPERTIES FOLDER "Examples" - COMPILE_FLAGS "${EXAMPLE_CMAKE_C_FLAGS}") diff --git a/examples/dse/gssapi/gssapi_proxy.c b/examples/dse/gssapi/gssapi_proxy.c deleted file mode 100644 index e5382a308..000000000 --- a/examples/dse/gssapi/gssapi_proxy.c +++ /dev/null @@ -1,158 +0,0 @@ -/* - This is free and unencumbered software released into the public domain. - - Anyone is free to copy, modify, publish, use, compile, sell, or - distribute this software, either in source code form or as a compiled - binary, for any purpose, commercial or non-commercial, and by any - means. - - In jurisdictions that recognize copyright laws, the author or authors - of this software dedicate any and all copyright interest in the - software to the public domain. We make this dedication for the benefit - of the public at large and to the detriment of our heirs and - successors. We intend this dedication to be an overt act of - relinquishment in perpetuity of all present and future rights to this - software under copyright law. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - - For more information, please refer to -*/ - -#include -#include - -/* - * This example program assumes that the following setup is done in DSE apriori: - * - * 1. DSE is configured to authenticate with Kerberos. - * 2. Using cqlsh as an administrator user (e.g. cassandra), create the following - * objects and grant permissions for them: - * - CREATE ROLE target_user WITH PASSWORD = 'target_user' and LOGIN = true; - CREATE KEYSPACE examples WITH REPLICATION = {'class': 'SimpleStrategy', 'replication_factor': - 1}; CREATE TABLE examples.gss_proxy_auth (f1 int PRIMARY KEY, f2 int); INSERT INTO - examples.gss_proxy_auth (f1, f2) VALUES (1, 2); GRANT ALL ON examples.gss_proxy_auth TO - target_user; - - GRANT PROXY.LOGIN ON ROLE 'target_user' to 'dseuser@DATASTAX.COM'; - * - * Substitute your own Kerberos user for 'dseuser@DATASTAX.COM' (in the above cql and - * the KERBEROS_USER macro below). - * - * Note that proxy auth can target an internal user (e.g. target_user) even if the authenticated - * user is from Kerberos. - */ - -#define KERBEROS_USER "dseuser@DATASTAX.COM" - -void print_error(CassFuture* future) { - const char* message; - size_t message_length; - cass_future_error_message(future, &message, &message_length); - fprintf(stderr, "Error: %.*s\n", (int)message_length, message); -} - -CassError select_and_dump(CassSession* session) { - CassError rc = CASS_OK; - CassStatement* statement = NULL; - CassFuture* future = NULL; - const char* query = "SELECT * FROM examples.gss_proxy_auth"; - - statement = cass_statement_new(query, 0); - future = cass_session_execute(session, statement); - - rc = cass_future_error_code(future); - if (rc != CASS_OK) { - print_error(future); - } else { - const CassResult* result = cass_future_get_result(future); - CassIterator* iterator = cass_iterator_from_result(result); - - if (cass_iterator_next(iterator)) { - int f1, f2; - const CassRow* row = cass_iterator_get_row(iterator); - if (cass_value_get_int32(cass_row_get_column(row, 0), &f1) != CASS_OK || - cass_value_get_int32(cass_row_get_column(row, 1), &f2) != CASS_OK) { - print_error(future); - } else { - printf("f1: %d f2: %d\n", f1, f2); - } - } - - cass_result_free(result); - cass_iterator_free(iterator); - } - - cass_future_free(future); - cass_statement_free(statement); - - return rc; -} - -CassError connect_session(CassSession* session, const CassCluster* cluster) { - CassError rc = CASS_OK; - CassFuture* future = cass_session_connect(session, cluster); - - rc = cass_future_error_code(future); - if (rc != CASS_OK) { - print_error(future); - } - cass_future_free(future); - - return rc; -} - -void connect_and_run(const char* hosts, const char* proxy_user) { - CassCluster* cluster = cass_cluster_new(); - CassSession* session = cass_session_new(); - - /* Add contact points */ - cass_cluster_set_contact_points(cluster, hosts); - - /* Hostname resolution is typically necessary when authenticating with Kerberos. */ - cass_cluster_set_use_hostname_resolution(cluster, cass_true); - - /* Authenticate as the Kerberos user. If proxy_user is non-null, - * declare that we want to execute all statements as proxy_user. */ - if (proxy_user == NULL) { - cass_cluster_set_dse_gssapi_authenticator(cluster, "dse", KERBEROS_USER); - } else { - cass_cluster_set_dse_gssapi_authenticator_proxy(cluster, "dse", KERBEROS_USER, "target_user"); - } - - if (connect_session(session, cluster) != CASS_OK) { - cass_cluster_free(cluster); - cass_session_free(session); - return; - } - - select_and_dump(session); - - cass_cluster_free(cluster); - cass_session_free(session); -} - -int main(int argc, char* argv[]) { - /* Setup and connect to cluster */ - char* hosts = "127.0.0.1"; - if (argc > 1) { - hosts = argv[1]; - } - - /* Enable info logging if desired. */ - /* cass_log_set_level(CASS_LOG_INFO); */ - - printf("Running a query without a proxy user should fail:\n"); - connect_and_run(hosts, NULL); - printf("\nRunning a query with proxy user 'target_user' should succeed:\n"); - connect_and_run(hosts, "target_user"); - - return 0; -} diff --git a/examples/dse/plaintext/.gitignore b/examples/dse/plaintext/.gitignore deleted file mode 100644 index 1cd89bb14..000000000 --- a/examples/dse/plaintext/.gitignore +++ /dev/null @@ -1 +0,0 @@ -plaintext diff --git a/examples/dse/plaintext/CMakeLists.txt b/examples/dse/plaintext/CMakeLists.txt deleted file mode 100644 index 5218798e3..000000000 --- a/examples/dse/plaintext/CMakeLists.txt +++ /dev/null @@ -1,25 +0,0 @@ -cmake_minimum_required(VERSION 3.15) - -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ".") - -# Set up rules/commands for building plaintext example -set(PROJECT_EXAMPLE_NAME plaintext) -set(EXAMPLE_SRC_FILES plaintext.c) -include_directories(${INCLUDES}) -add_executable(${PROJECT_EXAMPLE_NAME} ${EXAMPLE_SRC_FILES}) -target_link_libraries(${PROJECT_EXAMPLE_NAME} ${PROJECT_LIB_NAME_TARGET} ${DSE_LIBS}) -add_dependencies(${PROJECT_EXAMPLE_NAME} ${PROJECT_LIB_NAME_TARGET}) - -set_target_properties(${PROJECT_EXAMPLE_NAME} PROPERTIES FOLDER "Examples" - COMPILE_FLAGS "${EXAMPLE_CMAKE_C_FLAGS}") - -# Set up rules/commands for building plaintext_proxy example -set(PROJECT_EXAMPLE_NAME plaintext_proxy) -set(EXAMPLE_SRC_FILES plaintext_proxy.c) -include_directories(${INCLUDES}) -add_executable(${PROJECT_EXAMPLE_NAME} ${EXAMPLE_SRC_FILES}) -target_link_libraries(${PROJECT_EXAMPLE_NAME} ${PROJECT_LIB_NAME_TARGET} ${DSE_LIBS}) -add_dependencies(${PROJECT_EXAMPLE_NAME} ${PROJECT_LIB_NAME_TARGET}) - -set_target_properties(${PROJECT_EXAMPLE_NAME} PROPERTIES FOLDER "Examples" - COMPILE_FLAGS "${EXAMPLE_CMAKE_C_FLAGS}") diff --git a/examples/dse/plaintext/plaintext.c b/examples/dse/plaintext/plaintext.c deleted file mode 100644 index 04e9c0b03..000000000 --- a/examples/dse/plaintext/plaintext.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - This is free and unencumbered software released into the public domain. - - Anyone is free to copy, modify, publish, use, compile, sell, or - distribute this software, either in source code form or as a compiled - binary, for any purpose, commercial or non-commercial, and by any - means. - - In jurisdictions that recognize copyright laws, the author or authors - of this software dedicate any and all copyright interest in the - software to the public domain. We make this dedication for the benefit - of the public at large and to the detriment of our heirs and - successors. We intend this dedication to be an overt act of - relinquishment in perpetuity of all present and future rights to this - software under copyright law. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - - For more information, please refer to -*/ - -#include - -#include -#include - -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,127.0.0.2,127.0.0.3"; - if (argc > 1) { - hosts = argv[1]; - } - - /* Add contact points */ - cass_cluster_set_contact_points(cluster, hosts); - - cass_cluster_set_dse_plaintext_authenticator(cluster, "cassandra", "cassandra"); - - /* 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; - - printf("Successfully connected!\n"); - - /* 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; -} diff --git a/examples/dse/plaintext/plaintext_proxy.c b/examples/dse/plaintext/plaintext_proxy.c deleted file mode 100644 index 95b186784..000000000 --- a/examples/dse/plaintext/plaintext_proxy.c +++ /dev/null @@ -1,149 +0,0 @@ -/* - This is free and unencumbered software released into the public domain. - - Anyone is free to copy, modify, publish, use, compile, sell, or - distribute this software, either in source code form or as a compiled - binary, for any purpose, commercial or non-commercial, and by any - means. - - In jurisdictions that recognize copyright laws, the author or authors - of this software dedicate any and all copyright interest in the - software to the public domain. We make this dedication for the benefit - of the public at large and to the detriment of our heirs and - successors. We intend this dedication to be an overt act of - relinquishment in perpetuity of all present and future rights to this - software under copyright law. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - - For more information, please refer to -*/ - -#include -#include - -/* - * This example program assumes that the following setup is done in DSE apriori: - * - * 1. DSE is configured to authenticate with internal authentication or LDAP. - * 2. Using cqlsh as an administrator user (e.g. cassandra), create the following - * objects and grant permissions for them: - * - CREATE ROLE target_user WITH PASSWORD = 'target_user' and LOGIN = true; - CREATE ROLE service_user WITH PASSWORD = 'service_user' and LOGIN = true; - CREATE KEYSPACE examples WITH REPLICATION = {'class': 'SimpleStrategy', 'replication_factor': - 1}; CREATE TABLE examples.plaintext_proxy_auth (f1 int PRIMARY KEY, f2 int); INSERT INTO - examples.plaintext_proxy_auth (f1, f2) VALUES (1, 2); GRANT ALL ON examples.plaintext_proxy_auth TO - target_user; - - GRANT PROXY.LOGIN ON ROLE 'target_user' to 'service_user'; - */ - -void print_error(CassFuture* future) { - const char* message; - size_t message_length; - cass_future_error_message(future, &message, &message_length); - fprintf(stderr, "Error: %.*s\n", (int)message_length, message); -} - -CassError select_and_dump(CassSession* session) { - CassError rc = CASS_OK; - CassStatement* statement = NULL; - CassFuture* future = NULL; - const char* query = "SELECT * FROM examples.plaintext_proxy_auth"; - - statement = cass_statement_new(query, 0); - future = cass_session_execute(session, statement); - - rc = cass_future_error_code(future); - if (rc != CASS_OK) { - print_error(future); - } else { - const CassResult* result = cass_future_get_result(future); - CassIterator* iterator = cass_iterator_from_result(result); - - if (cass_iterator_next(iterator)) { - int f1, f2; - const CassRow* row = cass_iterator_get_row(iterator); - if (cass_value_get_int32(cass_row_get_column(row, 0), &f1) != CASS_OK || - cass_value_get_int32(cass_row_get_column(row, 1), &f2) != CASS_OK) { - print_error(future); - } else { - printf("f1: %d f2: %d\n", f1, f2); - } - } - - cass_result_free(result); - cass_iterator_free(iterator); - } - - cass_future_free(future); - cass_statement_free(statement); - - return rc; -} - -CassError connect_session(CassSession* session, const CassCluster* cluster) { - CassError rc = CASS_OK; - CassFuture* future = cass_session_connect(session, cluster); - - rc = cass_future_error_code(future); - if (rc != CASS_OK) { - print_error(future); - } - cass_future_free(future); - - return rc; -} - -void connect_and_run(const char* hosts, const char* proxy_user) { - CassCluster* cluster = cass_cluster_new(); - CassSession* session = cass_session_new(); - - /* Add contact points */ - cass_cluster_set_contact_points(cluster, hosts); - - /* Authenticate as service_user. If proxy_user is non-null, - * declare that we want to execute all statements as proxy_user. */ - if (proxy_user == NULL) { - cass_cluster_set_dse_plaintext_authenticator(cluster, "service_user", "service_user"); - } else { - cass_cluster_set_dse_plaintext_authenticator_proxy(cluster, "service_user", "service_user", - proxy_user); - } - - if (connect_session(session, cluster) != CASS_OK) { - cass_cluster_free(cluster); - cass_session_free(session); - return; - } - - select_and_dump(session); - - cass_cluster_free(cluster); - cass_session_free(session); -} - -int main(int argc, char* argv[]) { - /* Setup and connect to cluster */ - const char* hosts = "127.0.0.1"; - if (argc > 1) { - hosts = argv[1]; - } - - /* Enable info logging if desired. */ - /* cass_log_set_level(CASS_LOG_INFO); */ - - printf("Running a query without a proxy user should fail:\n"); - connect_and_run(hosts, NULL); - printf("\nRunning a query with proxy user 'target_user' should succeed:\n"); - connect_and_run(hosts, "target_user"); - - return 0; -} diff --git a/examples/dse/proxy_execution/CMakeLists.txt b/examples/dse/proxy_execution/CMakeLists.txt deleted file mode 100644 index 7e7cf0baa..000000000 --- a/examples/dse/proxy_execution/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -cmake_minimum_required(VERSION 3.15) - -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ".") -set(PROJECT_EXAMPLE_NAME proxy_execution) - -file(GLOB EXAMPLE_SRC_FILES *.c) -include_directories(${INCLUDES}) -add_executable(${PROJECT_EXAMPLE_NAME} ${EXAMPLE_SRC_FILES}) -target_link_libraries(${PROJECT_EXAMPLE_NAME} ${PROJECT_LIB_NAME_TARGET} ${DSE_LIBS}) -add_dependencies(${PROJECT_EXAMPLE_NAME} ${PROJECT_LIB_NAME_TARGET}) - -set_target_properties(${PROJECT_EXAMPLE_NAME} PROPERTIES FOLDER "Examples" - COMPILE_FLAGS "${EXAMPLE_CMAKE_C_FLAGS}") diff --git a/examples/dse/proxy_execution/proxy_execution.c b/examples/dse/proxy_execution/proxy_execution.c deleted file mode 100644 index de41e0102..000000000 --- a/examples/dse/proxy_execution/proxy_execution.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - This is free and unencumbered software released into the public domain. - - Anyone is free to copy, modify, publish, use, compile, sell, or - distribute this software, either in source code form or as a compiled - binary, for any purpose, commercial or non-commercial, and by any - means. - - In jurisdictions that recognize copyright laws, the author or authors - of this software dedicate any and all copyright interest in the - software to the public domain. We make this dedication for the benefit - of the public at large and to the detriment of our heirs and - successors. We intend this dedication to be an overt act of - relinquishment in perpetuity of all present and future rights to this - software under copyright law. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - - For more information, please refer to -*/ - -#include -#include - -/* - * This example program assumes that the following setup is done in DSE apriori: - * - * 1. DSE is configured to authenticate with internal authentication or LDAP. - * 2. Using cqlsh as an administrator user (e.g. cassandra), create the following - * objects and grant permissions for them: - - CREATE ROLE target_user WITH PASSWORD = 'target_user' and LOGIN = true; - CREATE ROLE service_user WITH PASSWORD = 'service_user' and LOGIN = true; - CREATE KEYSPACE examples WITH REPLICATION = {'class': 'SimpleStrategy', 'replication_factor': - 1}; CREATE TABLE examples.proxy_execution (f1 int PRIMARY KEY, f2 int); INSERT INTO - examples.proxy_execution (f1, f2) VALUES (1, 2); GRANT ALL ON examples.proxy_execution TO - target_user; - - GRANT PROXY.EXECUTE ON ROLE 'target_user' to 'service_user'; - * 3. Verify that service_user cannot query examples.proxy_execution (in cqlsh). - */ - -void print_error(CassFuture* future) { - const char* message; - size_t message_length; - cass_future_error_message(future, &message, &message_length); - fprintf(stderr, "Error: %.*s\n", (int)message_length, message); -} - -CassError select_and_dump(CassSession* session, const char* execute_as) { - CassError rc = CASS_OK; - CassStatement* statement = NULL; - CassFuture* future = NULL; - const char* query = "SELECT * FROM examples.proxy_execution"; - - statement = cass_statement_new(query, 0); - if (execute_as != NULL) { - cass_statement_set_execute_as(statement, execute_as); - } - future = cass_session_execute(session, statement); - - rc = cass_future_error_code(future); - if (rc != CASS_OK) { - print_error(future); - } else { - const CassResult* result = cass_future_get_result(future); - CassIterator* iterator = cass_iterator_from_result(result); - - if (cass_iterator_next(iterator)) { - int f1, f2; - const CassRow* row = cass_iterator_get_row(iterator); - if (cass_value_get_int32(cass_row_get_column(row, 0), &f1) != CASS_OK || - cass_value_get_int32(cass_row_get_column(row, 1), &f2) != CASS_OK) { - print_error(future); - } else { - printf("f1: %d f2: %d\n", f1, f2); - } - } - - cass_result_free(result); - cass_iterator_free(iterator); - } - - cass_future_free(future); - cass_statement_free(statement); - - return rc; -} - -CassError connect_session(CassSession* session, const CassCluster* cluster) { - CassError rc = CASS_OK; - CassFuture* future = cass_session_connect(session, cluster); - - rc = cass_future_error_code(future); - if (rc != CASS_OK) { - print_error(future); - } - cass_future_free(future); - - return rc; -} - -int main(int argc, char* argv[]) { - /* Setup and connect to cluster */ - CassCluster* cluster = cass_cluster_new(); - CassSession* session = cass_session_new(); - char* hosts = "127.0.0.1"; - if (argc > 1) { - hosts = argv[1]; - } - - /* Enable info logging if desired. */ - /* cass_log_set_level(CASS_LOG_INFO); */ - - /* Add contact points */ - cass_cluster_set_contact_points(cluster, hosts); - - /* Authenticate as the service_user */ - cass_cluster_set_dse_plaintext_authenticator(cluster, "service_user", "service_user"); - - if (connect_session(session, cluster) != CASS_OK) { - cass_cluster_free(cluster); - cass_session_free(session); - return -1; - } - - printf("Running a query without a proxy user should fail:\n"); - select_and_dump(session, NULL); - printf("\nRunning a query with proxy user 'target_user' should succeed:\n"); - select_and_dump(session, "target_user"); - - cass_cluster_free(cluster); - cass_session_free(session); - - return 0; -} diff --git a/scylla-rust-wrapper/CMakeLists.txt b/scylla-rust-wrapper/CMakeLists.txt index 881e62506..a0356c90f 100644 --- a/scylla-rust-wrapper/CMakeLists.txt +++ b/scylla-rust-wrapper/CMakeLists.txt @@ -27,7 +27,7 @@ else() set(CMAKE_Rust_FLAGS "--cfg cpp_rust_unstable") endif() -if(CASS_BUILD_INTEGRATION_TESTS) +if(CASS_BUILD_INTEGRATION_TESTS OR CASS_BUILD_EXAMPLES) set(CMAKE_Rust_FLAGS "${CMAKE_Rust_FLAGS} --cfg cpp_integration_testing") endif() diff --git a/scylla-rust-wrapper/build.rs b/scylla-rust-wrapper/build.rs index 265c8c237..917d6439e 100644 --- a/scylla-rust-wrapper/build.rs +++ b/scylla-rust-wrapper/build.rs @@ -158,4 +158,19 @@ fn main() { &["CassMetrics_", "CassMetrics"], &out_path, ); + prepare_cppdriver_data( + "cppdriver_authenticator_types.rs", + &[ + "CassAuthenticator", + "CassAuthenticatorCallbacks", + "CassAuthenticatorDataCleanupCallback", + ], + &out_path, + ); + prepare_cppdriver_data( + "cppdriver_host_listener_types.rs", + &["CassHostListenerEvent", "CassHostListenerCallback"], + &out_path, + ); + prepare_cppdriver_data("cppdriver_version_types.rs", &["CassVersion"], &out_path); } diff --git a/scylla-rust-wrapper/src/api.rs b/scylla-rust-wrapper/src/api.rs index f44772da2..6e28bc8e4 100644 --- a/scylla-rust-wrapper/src/api.rs +++ b/scylla-rust-wrapper/src/api.rs @@ -974,12 +974,40 @@ pub mod integration_testing { // Disabling rustfmt to have one item per line for better readability. #[rustfmt::skip] pub use crate::integration_testing::stubs::{ + CassAggregateMeta, + CassAuthenticator, CassCustomPayload, + CassFunctionMeta, + CassIndexMeta, + cass_aggregate_meta_name, + cass_authenticator_response, + cass_cluster_set_authenticator_callbacks, + cass_cluster_set_cloud_secure_connection_bundle, + cass_cluster_set_host_listener_callback, + cass_cluster_set_num_threads_io, + cass_cluster_set_queue_size_io, cass_cluster_set_cloud_secure_connection_bundle_n, cass_cluster_set_exponential_reconnect, cass_cluster_set_use_randomized_contact_points, cass_custom_payload_new, + cass_function_meta_name, cass_future_custom_payload_item, cass_future_custom_payload_item_count, + cass_index_meta_name, + 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_table_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_function_by_name, + cass_schema_meta_version, + cass_statement_add_key_index, + cass_statement_set_keyspace, }; } diff --git a/scylla-rust-wrapper/src/integration_testing.rs b/scylla-rust-wrapper/src/integration_testing.rs index c3435042b..0f76af0de 100644 --- a/scylla-rust-wrapper/src/integration_testing.rs +++ b/scylla-rust-wrapper/src/integration_testing.rs @@ -362,13 +362,24 @@ pub unsafe extern "C" fn testing_retry_policy_ignoring_new() )))) } -/// Stubs of functions that must be implemented for the integration tests to compile, -/// but the proper implementation is not needed for the tests to run, -/// and at the same time the functions are not yet implemented in the wrapper. +/// Stubs of functions that must be implemented for the integration tests +/// or examples to compile, but the proper implementation is not needed for +/// the tests/examples to run, and at the same time the functions are not +/// yet implemented in the wrapper. pub(crate) mod stubs { + use std::ffi::c_void; + use super::*; - use crate::argconv::ptr_to_cstr_n; + use crate::argconv::{CassOwnedExclusivePtr, CassPtr, ptr_to_cstr_n, strlen}; + use crate::cass_authenticator_types::{ + CassAuthenticatorCallbacks, CassAuthenticatorDataCleanupCallback, + }; use crate::cass_error_types::CassError; + use crate::cass_host_listener_types::CassHostListenerCallback; + use crate::cass_version_types::CassVersion; + use crate::iterator::CassIterator; + use crate::metadata::{CassColumnMeta, CassKeyspaceMeta, CassSchemaMeta, CassTableMeta}; + use crate::query_result::CassValue; use crate::types::cass_byte_t; pub struct CassCustomPayload; @@ -383,6 +394,16 @@ pub(crate) mod stubs { CassError::CASS_OK } + #[unsafe(no_mangle)] + pub unsafe extern "C" fn cass_cluster_set_cloud_secure_connection_bundle( + cluster_raw: CassBorrowedExclusivePtr, + path: *const c_char, + ) -> CassError { + unsafe { + cass_cluster_set_cloud_secure_connection_bundle_n(cluster_raw, path, strlen(path)) + } + } + #[unsafe(no_mangle)] pub unsafe extern "C" fn cass_cluster_set_cloud_secure_connection_bundle_n( _cluster_raw: CassBorrowedExclusivePtr, @@ -452,4 +473,193 @@ pub(crate) mod stubs { ) -> size_t { 0 } + + #[unsafe(no_mangle)] + pub extern "C" fn cass_cluster_set_authenticator_callbacks( + _cluster_raw: CassBorrowedExclusivePtr, + _callbacks: CassBorrowedSharedPtr, + _cleanup_callback: CassAuthenticatorDataCleanupCallback, + _data: *mut c_void, + ) -> CassError { + CassError::CASS_OK + } + + pub struct CassAuthenticator; + + #[unsafe(no_mangle)] + pub extern "C" fn cass_authenticator_response( + _auth: CassBorrowedExclusivePtr, + _size: size_t, + ) -> *mut c_char { + std::ptr::null_mut() + } + + #[unsafe(no_mangle)] + pub extern "C" fn cass_statement_add_key_index( + _statement: CassBorrowedExclusivePtr, + _index: size_t, + ) -> CassError { + CassError::CASS_OK + } + + #[unsafe(no_mangle)] + pub extern "C" fn cass_statement_set_keyspace( + _statement: CassBorrowedExclusivePtr, + _keyspace: *const c_char, + ) -> CassError { + CassError::CASS_OK + } + + #[unsafe(no_mangle)] + pub extern "C" fn cass_cluster_set_host_listener_callback( + _cluster_raw: CassBorrowedExclusivePtr, + _callback: CassHostListenerCallback, + _data: *mut c_void, + ) -> CassError { + CassError::CASS_OK + } + + #[unsafe(no_mangle)] + pub extern "C" fn cass_cluster_set_num_threads_io( + _cluster_raw: CassBorrowedExclusivePtr, + _num_threads: u32, + ) -> CassError { + CassError::CASS_OK + } + + #[unsafe(no_mangle)] + pub extern "C" fn cass_cluster_set_queue_size_io( + _cluster_raw: CassBorrowedExclusivePtr, + _queue_size: u32, + ) -> CassError { + CassError::CASS_OK + } + + #[unsafe(no_mangle)] + pub extern "C" fn cass_iterator_get_meta_field_name( + _cass_iterator: CassBorrowedSharedPtr, + _name: *mut *const c_char, + _name_length: *mut size_t, + ) { + } + + #[unsafe(no_mangle)] + pub extern "C" fn cass_schema_meta_version( + _schema_meta: CassBorrowedSharedPtr, + ) -> CassVersion { + CassVersion { + major_version: 2, + minor_version: 1, + patch_version: 3, + } + } + + #[unsafe(no_mangle)] + pub extern "C" fn cass_iterator_get_meta_field_value<'schema>( + _cass_iterator: CassBorrowedSharedPtr, CConst>, + ) -> CassOwnedExclusivePtr, CMut> { + CassPtr::null_mut() + } + + #[unsafe(no_mangle)] + pub extern "C" fn cass_iterator_indexes_from_table_meta( + _cass_table_meta: CassBorrowedSharedPtr, + ) -> CassOwnedExclusivePtr { + CassPtr::null_mut() + } + + #[unsafe(no_mangle)] + pub extern "C" fn cass_iterator_fields_from_column_meta( + _cass_column_meta: CassBorrowedSharedPtr, + ) -> CassOwnedExclusivePtr { + CassPtr::null_mut() + } + + #[unsafe(no_mangle)] + pub extern "C" fn cass_iterator_fields_from_table_meta( + _cass_table_meta: CassBorrowedSharedPtr, + ) -> CassOwnedExclusivePtr { + CassPtr::null_mut() + } + + #[unsafe(no_mangle)] + pub extern "C" fn cass_iterator_fields_from_keyspace_meta( + _cass_keyspace_meta: CassBorrowedSharedPtr, + ) -> CassOwnedExclusivePtr { + CassPtr::null_mut() + } + + pub struct CassFunctionMeta; + + #[unsafe(no_mangle)] + pub extern "C" fn cass_function_meta_name( + _cass_function_meta: CassBorrowedSharedPtr, + _name: *mut *const c_char, + _name_length: *mut size_t, + ) { + } + + #[unsafe(no_mangle)] + pub extern "C" fn cass_iterator_fields_from_function_meta( + _cass_function_meta: CassBorrowedSharedPtr, + ) -> CassOwnedExclusivePtr { + CassPtr::null_mut() + } + + pub struct CassIndexMeta; + + #[unsafe(no_mangle)] + pub extern "C" fn cass_iterator_get_index_meta<'schema>( + _cass_iterator: CassBorrowedSharedPtr, CConst>, + ) -> CassBorrowedSharedPtr<'schema, CassIndexMeta, CConst> { + CassPtr::null() + } + + #[unsafe(no_mangle)] + pub extern "C" fn cass_index_meta_name( + _cass_index_meta: CassBorrowedSharedPtr, + _name: *mut *const c_char, + _name_length: *mut size_t, + ) { + } + + #[unsafe(no_mangle)] + pub extern "C" fn cass_iterator_fields_from_index_meta( + _cass_index_meta: CassBorrowedSharedPtr, + ) -> CassOwnedExclusivePtr { + CassPtr::null_mut() + } + + #[unsafe(no_mangle)] + pub unsafe extern "C" fn cass_keyspace_meta_function_by_name( + _keyspace_meta: CassBorrowedSharedPtr, + _function: *const c_char, + ) -> CassBorrowedSharedPtr { + CassPtr::null() + } + + pub struct CassAggregateMeta; + + #[unsafe(no_mangle)] + pub extern "C" fn cass_aggregate_meta_name( + _cass_aggregate_meta: CassBorrowedSharedPtr, + _name: *mut *const c_char, + _name_length: *mut size_t, + ) { + } + + #[unsafe(no_mangle)] + pub extern "C" fn cass_iterator_fields_from_aggregate_meta( + _cass_aggregate_meta: CassBorrowedSharedPtr, + ) -> CassOwnedExclusivePtr { + CassPtr::null_mut() + } + + #[unsafe(no_mangle)] + pub unsafe extern "C" fn cass_keyspace_meta_aggregate_by_name( + _keyspace_meta: CassBorrowedSharedPtr, + _aggregate: *const c_char, + ) -> CassBorrowedSharedPtr { + CassPtr::null() + } } diff --git a/scylla-rust-wrapper/src/lib.rs b/scylla-rust-wrapper/src/lib.rs index 3367e4ed9..621f10274 100644 --- a/scylla-rust-wrapper/src/lib.rs +++ b/scylla-rust-wrapper/src/lib.rs @@ -164,6 +164,33 @@ pub(crate) mod cass_metrics_types { include_bindgen_generated!("cppdriver_metrics_types.rs"); } +/// CassAuthenticator +pub(crate) mod cass_authenticator_types { + #![allow(unused)] + #![allow(non_camel_case_types, non_snake_case)] + #![allow(unreachable_pub, unnameable_types)] + + include_bindgen_generated!("cppdriver_authenticator_types.rs"); +} + +/// CassHostListenerEvent, CassHostListenerCallback +pub(crate) mod cass_host_listener_types { + #![allow(unused)] + #![allow(non_camel_case_types, non_snake_case)] + #![allow(unreachable_pub, unnameable_types)] + + include_bindgen_generated!("cppdriver_host_listener_types.rs"); +} + +/// CassVersion +pub(crate) mod cass_version_types { + #![allow(unused)] + #![allow(non_camel_case_types, non_snake_case)] + #![allow(unreachable_pub, unnameable_types)] + + include_bindgen_generated!("cppdriver_version_types.rs"); +} + pub(crate) static RUNTIME: LazyLock = LazyLock::new(|| Runtime::new().unwrap()); pub(crate) static LOGGER: LazyLock> = LazyLock::new(|| { RwLock::new(Logger { diff --git a/tests/examples_cluster/docker-compose.yml b/tests/examples_cluster/docker-compose.yml new file mode 100644 index 000000000..999a322a8 --- /dev/null +++ b/tests/examples_cluster/docker-compose.yml @@ -0,0 +1,33 @@ +networks: + public: + name: scylla_cpp_driver_public + driver: bridge + ipam: + driver: default + config: + - subnet: 172.43.0.0/16 +services: + scylla: + image: scylladb/scylla + networks: + public: + ipv4_address: 172.43.0.2 + command: | + --rpc-address 172.43.0.2 + --listen-address 172.43.0.2 + --skip-wait-for-gossip-to-settle 0 + --ring-delay-ms 0 + --smp 2 + --memory 1G + healthcheck: + test: + [ + "CMD", + "cqlsh", + "scylla", + "-e", + "select * from system.local WHERE key='local'", + ] + interval: 5s + timeout: 5s + retries: 60