Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(DOCSP-35298): C++: Remove BSON from Function examples #3144

Merged
merged 3 commits into from
Jan 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion examples/cpp/sync/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,12 @@ FetchContent_Declare(
GIT_REPOSITORY https://github.com/realm/realm-cpp.git
GIT_TAG 8eba9728ea535a6cd78beaef37ed6d22b73fe889
)
FetchContent_Declare(
json
URL https://github.com/nlohmann/json/releases/download/v3.11.3/json.tar.xz
)

FetchContent_MakeAvailable(Catch2 cpprealm)
FetchContent_MakeAvailable(Catch2 cpprealm json)

add_executable(examples-sync
app.cpp
Expand All @@ -32,3 +36,4 @@ add_executable(examples-sync

target_link_libraries(examples-sync PRIVATE Catch2::Catch2WithMain)
target_link_libraries(examples-sync PRIVATE cpprealm)
target_link_libraries(examples-sync PRIVATE nlohmann_json::nlohmann_json)
34 changes: 16 additions & 18 deletions examples/cpp/sync/authentication.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,24 +53,22 @@ TEST_CASE("create and log in an anonymous user", "[realm][sync]") {
REQUIRE(user.access_token().empty());
}

// TODO: Figure out how to do this properly in the updated SDK
// TEST_CASE("test custom function authentication", "[realm][sync]") {
// // :snippet-start: custom-function
// // Custom function authentication takes a BSON Document with parameters.
// // The parameter details vary depending on how you define your custom
// authentication function. realm::bson::BsonDocument params = {{
// "username", "bob" }};

// auto appConfig = realm::App::configuration();
// appConfig.app_id = APP_ID;
// auto app = realm::App(appConfig);

// auto user = app.login(realm::App::credentials::function(params)).get();
// // :snippet-end:
// REQUIRE(!user.access_token().empty());
// user.log_out().get();
// REQUIRE(user.access_token().empty());
// }
TEST_CASE("test custom function authentication", "[realm][sync]") {
// :snippet-start: custom-function
auto appConfig = realm::App::configuration();
appConfig.app_id = APP_ID;
auto app = realm::App(appConfig);

/* Custom function authentication takes a string parameters argument.
The parameter details vary depending on how you define your custom
authentication function. */
std::string params = "{\"username\": \"bob\"}";
auto user = app.login(realm::App::credentials::function(params)).get();
// :snippet-end:
REQUIRE(!user.access_token().empty());
user.log_out().get();
REQUIRE(user.access_token().empty());
}

TEST_CASE("test get user access token", "[realm][sync]") {
auto appConfig = realm::App::configuration();
Expand Down
28 changes: 8 additions & 20 deletions examples/cpp/sync/call-function.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,6 @@

static const std::string APP_ID = "cpp-tester-uliix";

// This test is currently commented out because the SDK has removed the
// exposed Core headers that gave it access to a BSON library.
// See PR https://github.com/realm/realm-cpp/pull/123/
// Per Lee, a separate project will create a C++ SDK BSON library, but in
// the meantime, I'll need to use some other library to make this test work.
// I need to figure out how to create BSON strings in C++ and pass them
// instead of using realm::bson::Bson for the params.
// TODO: Figure out what library to use and how to make this test/example work.
#if 0
TEST_CASE("call a function", "[realm][sync]") {
// :snippet-start: call-a-function
// Connect to an App Services App and authenticate a user
Expand All @@ -25,24 +16,21 @@ TEST_CASE("call a function", "[realm][sync]") {
auto user = app.login(realm::App::credentials::anonymous()).get();
auto sync_config = user.flexible_sync_configuration();

// If a function takes arguments, pass them as BSON
auto arg1 = realm::bson::Bson("john.smith");
auto arg2 = realm::bson::Bson("@companyemail.com");
// If the function takes arguments, pass them as a string array.
// Any quotes within the array must be escaped.
auto argArray = "[\"john.smith\", \"@companyemail.com\"]";

// Call an App Services function as the logged-in user
auto result = user.call_function("concatenate", {arg1, arg2}).get();
auto result = user.call_function("concatenate", argArray).get();

// Verify that the result has a value
CHECK(result);
auto bsonResult = result.value();
auto functionResult = result.value();

// Translate the BSON result back to a string
auto resultString = std::string(bsonResult);
// Prints "Calling the concatenate function returned
// [email protected]."
std::cout << "Calling the concatenate function returned " << resultString
// "[email protected]"."
std::cout << "Calling the concatenate function returned " << functionResult
<< ".\n";
// :snippet-end:
REQUIRE(resultString == "[email protected]");
REQUIRE(functionResult == "\"[email protected]\"");
}
#endif
103 changes: 55 additions & 48 deletions examples/cpp/sync/custom-user-data.cpp
Original file line number Diff line number Diff line change
@@ -1,55 +1,62 @@
#include <catch2/catch_test_macros.hpp>
#include <cpprealm/sdk.hpp>
#include <future>
#include <nlohmann/json.hpp>

static const std::string APP_ID = "cpp-tester-uliix";

// This test is currently commented out because the SDK has removed the
// exposed Core headers that gave it access to a BSON library.
// See PR https://github.com/realm/realm-cpp/pull/123/
// Per Lee, a separate project will create a C++ SDK BSON library, but in
// the meantime, I'll need to use some other library to make this test work.
// I need to figure out how to create BSON strings in C++ and pass them
// instead of using realm::bson::Bson for the params.
// TODO: Figure out what library to use and how to make this test/example work.
#if 0
TEST_CASE("custom user data", "[realm][sync]")
{
auto appConfig = realm::App::configuration();
appConfig.app_id = APP_ID;
auto app = realm::App(appConfig);

// :snippet-start: create
auto user = app.login(realm::App::credentials::anonymous()).get();

// Functions take an argument of BsonArray, so initialize the custom data as a BsonDocument
auto customDataBson = realm::bson::BsonDocument({{"userId", user.identifier()}, {"favoriteColor", "gold"}});

// Call an Atlas Function to insert custom data for the user
auto result = user.call_function("updateCustomUserData", { customDataBson }).get();
// :snippet-end:
CHECK(result);

// :snippet-start: read
// Custom user data could be stale, so refresh it before reading it
user.refresh_custom_user_data().get();
CHECK((*user.custom_data())["favoriteColor"] == "gold");
// :snippet-end:

// :snippet-start: update
// Functions take an argument of BsonArray, so initialize the custom data as a BsonDocument
auto updatedDataBson = realm::bson::BsonDocument({{"userId", user.identifier()}, { "favoriteColor", "black" }});

// Call an Atlas Function to update custom data for the user
auto updateResult = user.call_function("updateCustomUserData", { updatedDataBson }).get();

// Refresh the custom user data before reading it to verify it succeeded
user.refresh_custom_user_data().get();
CHECK((*user.custom_data())["favoriteColor"] == "black");
// :snippet-end:
// :snippet-start: delete
auto deleteResult = user.call_function("deleteCustomUserData", {}).get();
// :snippet-end:
CHECK(deleteResult);
TEST_CASE("custom user data", "[realm][sync]") {
auto appConfig = realm::App::configuration();
appConfig.app_id = APP_ID;
auto app = realm::App(appConfig);

// :snippet-start: create
auto user = app.login(realm::App::credentials::anonymous()).get();

// Functions take a string argument. Any quotes within the array must be
// escaped.
auto customData =
"[{\"userId\":\"" + user.identifier() + "\",\"favoriteColor\":\"gold\"}]";

// Call an Atlas Function to insert custom data for the user
auto result = user.call_function("updateCustomUserData", customData).get();
// :snippet-end:
CHECK(result);

// :snippet-start: read
// Custom user data could be stale, so refresh it before reading it
user.refresh_custom_user_data().get();
auto userData = user.custom_data().value();

/* Parse the string custom data to use it more easily in your code.
In this example, we're using the nlohmann/json library, but use whatever
works with your application's constraints. */
auto userDataObject = nlohmann::json::parse(userData);
CHECK(userDataObject["favoriteColor"] == "gold");
// :snippet-end:

// :snippet-start: update
// Functions take a string argument. Any quotes within the array must be
// escaped.
auto updatedData = "[{\"userId\":\"" + user.identifier() +
"\",\"favoriteColor\":\"black\"}]";

// Call an Atlas Function to update custom data for the user
auto updateResult =
user.call_function("updateCustomUserData", updatedData).get();

// Refresh the custom user data before reading it to verify it succeeded
user.refresh_custom_user_data().get();
auto updatedUserData = user.custom_data().value();

/* Parse the string custom data to use it more easily in your code.
In this example, we're using the nlohmann/json library, but use whatever
works with your application's constraints. */
auto updatedUserDataObject = nlohmann::json::parse(updatedUserData);
CHECK(updatedUserDataObject["favoriteColor"] == "black");
// :snippet-end:
// :snippet-start: delete
auto deleteResult = user.call_function("deleteCustomUserData", "[]").get();
// :snippet-end:
CHECK(deleteResult);
}
#endif
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
// // Custom function authentication takes a BSON Document with parameters.
// // The parameter details vary depending on how you define your custom
// authentication function. realm::bson::BsonDocument params = {{
// "username", "bob" }};
auto appConfig = realm::App::configuration();
appConfig.app_id = APP_ID;
auto app = realm::App(appConfig);

// auto appConfig = realm::App::configuration();
// appConfig.app_id = APP_ID;
// auto app = realm::App(appConfig);

// auto user = app.login(realm::App::credentials::function(params)).get();
/* Custom function authentication takes a string parameters argument.
The parameter details vary depending on how you define your custom
authentication function. */
std::string params = "{\"username\": \"bob\"}";
auto user = app.login(realm::App::credentials::function(params)).get();
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,18 @@ auto app = realm::App(appConfig);
auto user = app.login(realm::App::credentials::anonymous()).get();
auto sync_config = user.flexible_sync_configuration();

// If a function takes arguments, pass them as BSON
auto arg1 = realm::bson::Bson("john.smith");
auto arg2 = realm::bson::Bson("@companyemail.com");
// If the function takes arguments, pass them as a string array.
// Any quotes within the array must be escaped.
auto argArray = "[\"john.smith\", \"@companyemail.com\"]";

// Call an App Services function as the logged-in user
auto result = user.call_function("concatenate", {arg1, arg2}).get();
auto result = user.call_function("concatenate", argArray).get();

// Verify that the result has a value
CHECK(result);
auto bsonResult = result.value();
auto functionResult = result.value();

// Translate the BSON result back to a string
auto resultString = std::string(bsonResult);
// Prints "Calling the concatenate function returned
// [email protected]."
std::cout << "Calling the concatenate function returned " << resultString
// "[email protected]"."
std::cout << "Calling the concatenate function returned " << functionResult
<< ".\n";
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
auto user = app.login(realm::App::credentials::anonymous()).get();

// Functions take an argument of BsonArray, so initialize the custom data as a BsonDocument
auto customDataBson = realm::bson::BsonDocument({{"userId", user.identifier()}, {"favoriteColor", "gold"}});
// Functions take a string argument. Any quotes within the array must be
// escaped.
auto customData =
"[{\"userId\":\"" + user.identifier() + "\",\"favoriteColor\":\"gold\"}]";

// Call an Atlas Function to insert custom data for the user
auto result = user.call_function("updateCustomUserData", { customDataBson }).get();
auto result = user.call_function("updateCustomUserData", customData).get();
Original file line number Diff line number Diff line change
@@ -1 +1 @@
auto deleteResult = user.call_function("deleteCustomUserData", {}).get();
auto deleteResult = user.call_function("deleteCustomUserData", "[]").get();
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
// Custom user data could be stale, so refresh it before reading it
user.refresh_custom_user_data().get();
CHECK((*user.custom_data())["favoriteColor"] == "gold");
auto userData = user.custom_data().value();

/* Parse the string custom data to use it more easily in your code.
In this example, we're using the nlohmann/json library, but use whatever
works with your application's constraints. */
auto userDataObject = nlohmann::json::parse(userData);
CHECK(userDataObject["favoriteColor"] == "gold");
17 changes: 13 additions & 4 deletions source/examples/generated/cpp/custom-user-data.snippet.update.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
// Functions take an argument of BsonArray, so initialize the custom data as a BsonDocument
auto updatedDataBson = realm::bson::BsonDocument({{"userId", user.identifier()}, { "favoriteColor", "black" }});
// Functions take a string argument. Any quotes within the array must be
// escaped.
auto updatedData = "[{\"userId\":\"" + user.identifier() +
"\",\"favoriteColor\":\"black\"}]";

// Call an Atlas Function to update custom data for the user
auto updateResult = user.call_function("updateCustomUserData", { updatedDataBson }).get();
auto updateResult =
user.call_function("updateCustomUserData", updatedData).get();

// Refresh the custom user data before reading it to verify it succeeded
user.refresh_custom_user_data().get();
CHECK((*user.custom_data())["favoriteColor"] == "black");
auto updatedUserData = user.custom_data().value();

/* Parse the string custom data to use it more easily in your code.
In this example, we're using the nlohmann/json library, but use whatever
works with your application's constraints. */
auto updatedUserDataObject = nlohmann::json::parse(updatedUserData);
CHECK(updatedUserDataObject["favoriteColor"] == "black");
7 changes: 3 additions & 4 deletions source/sdk/cpp/app-services/call-a-function.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,10 @@ To execute a function from the C++ SDK, use the
:cpp-sdk:`call_function() <structrealm_1_1user.html#a82ab02822dd96e8d44201b996dd6ed0c>`
member function on the ``user`` object. Pass in the name of the
function as a string for the first parameter. This function takes two arguments,
which we provide as a ``BsonArray`` of arguments:
which we provide as a string array of arguments:

.. literalinclude:: /examples/generated/cpp/call-function.snippet.call-a-function.cpp
:language: cpp

The callback can provide an optional BSON result, or an optional error.
In the example above, we check that the result has a value, and then cast
it back to a string.
The callback can provide an optional string result, or an optional error.
In the example above, we check that the result has a value.
Loading