Skip to content

Commit 2146856

Browse files
authored
(DOCSP-26735): C++: Add a Quick Start page (#2575)
## Pull Request Info As part of this work, I removed the "LINQ" reference in the include that was shared across all the SDKs, and replaced it with the more generic "the SDK's query engine." ### Jira - https://jira.mongodb.org/browse/DOCSP-26735 ### Staged Changes - [Quick Start](https://docs-mongodbcom-staging.corp.mongodb.com/realm/docsworker-xlarge/DOCSP-26735/sdk/cpp/quick-start/) - [App Services](https://docs-mongodbcom-staging.corp.mongodb.com/realm/docsworker-xlarge/DOCSP-26735/sdk/cpp/application-services/) ### Reminder Checklist If your PR modifies the docs, you might need to also update some corresponding pages. Check if completed or N/A. - [x] Create Jira ticket for corresponding docs-app-services update(s), if any - [x] Checked/updated Admin API - [x] Checked/updated CLI reference ### Review Guidelines [REVIEWING.md](https://github.com/mongodb/docs-realm/blob/master/REVIEWING.md)
1 parent db5e1c0 commit 2146856

21 files changed

+563
-6
lines changed

examples/cpp/CMakeLists.txt

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,15 @@ FetchContent_Declare(
1919

2020
FetchContent_MakeAvailable(Catch2 cpprealm)
2121

22-
# add_executable(examples testHelpers.hpp testHelpersTests.cpp authentication.cpp define-object-model.cpp examples.cpp flexible-sync.cpp supported-types.cpp)
23-
add_executable(examples authentication.cpp define-object-model.cpp examples.cpp filter-data.cpp flexible-sync.cpp supported-types.cpp)
22+
add_executable(examples
23+
authentication.cpp
24+
define-object-model.cpp
25+
examples.cpp
26+
filter-data.cpp
27+
flexible-sync.cpp
28+
quick-start.cpp
29+
supported-types.cpp
30+
)
2431

2532
target_link_libraries(examples PRIVATE Catch2::Catch2WithMain)
2633
target_link_libraries(examples PRIVATE cpprealm)

examples/cpp/quick-start.cpp

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
#include <catch2/catch_test_macros.hpp>
2+
#include <thread>
3+
#include <future>
4+
#include <string>
5+
// :snippet-start: includes
6+
#include <cpprealm/sdk.hpp>
7+
// :snippet-end:
8+
9+
// :replace-start: {
10+
// "terms": {
11+
// "Local_": "",
12+
// "Sync_": "",
13+
// "userId.c_str()": "userId"
14+
// }
15+
// }
16+
17+
static const std::string APP_ID = "cpp-tester-uliix";
18+
19+
struct Local_Todo : realm::object<Local_Todo> {
20+
realm::persisted<std::string> name;
21+
realm::persisted<std::string> status;
22+
23+
static constexpr auto schema = realm::schema("Local_Todo",
24+
realm::property<&Local_Todo::name>("name"),
25+
realm::property<&Local_Todo::status>("status"));
26+
};
27+
28+
// :snippet-start: model
29+
struct Sync_Todo : realm::object<Sync_Todo> {
30+
realm::persisted<realm::object_id> _id{realm::object_id::generate()};
31+
realm::persisted<std::string> name;
32+
realm::persisted<std::string> status;
33+
// The ownerId property stores the user.identifier() of a
34+
// logged-in user. Omit this property for the non-sync example.
35+
realm::persisted<std::string> ownerId;
36+
37+
static constexpr auto schema = realm::schema("Sync_Todo",
38+
realm::property<&Sync_Todo::_id, true>("_id"),
39+
realm::property<&Sync_Todo::name>("name"),
40+
realm::property<&Sync_Todo::status>("status"),
41+
realm::property<&Sync_Todo::ownerId>("ownerId"));
42+
};
43+
// :snippet-end:
44+
45+
TEST_CASE("local quick start", "[realm][write]") {
46+
// :snippet-start: realm-open
47+
auto realm = realm::open<Local_Todo>();
48+
// :snippet-end:
49+
50+
// :snippet-start: create-todo
51+
auto todo = Local_Todo {
52+
.name = "Create my first todo item",
53+
.status = "In Progress"
54+
};
55+
56+
realm.write([&realm, &todo] {
57+
realm.add(todo);
58+
});
59+
// :snippet-end:
60+
61+
// :snippet-start: get-all-todos
62+
auto todos = realm.objects<Local_Todo>();
63+
// :snippet-end:
64+
CHECK(todos.size() == 1);
65+
66+
// :snippet-start: filter
67+
auto todosInProgress = todos.where([](auto const& todo) {
68+
return todo.status == "In Progress";
69+
});
70+
// :snippet-end:
71+
CHECK(todosInProgress.size() == 1);
72+
73+
// :snippet-start: watch-for-changes
74+
auto token = todo.observe([&](auto&& change) {
75+
try {
76+
if (change.error) {
77+
rethrow_exception(change.error);
78+
}
79+
if (change.is_deleted) {
80+
std::cout << "The object was deleted.\n";
81+
} else {
82+
for (auto& propertyChange : change.property_changes) {
83+
std::cout << "The object's " << propertyChange.name << " property has changed.\n";
84+
CHECK(propertyChange.name == "status"); // :remove:
85+
}
86+
}
87+
} catch (std::exception const& e) {
88+
std::cerr << "Error: " << e.what() << "\n";
89+
}
90+
});
91+
// :snippet-end:
92+
93+
// :snippet-start: modify-write-block
94+
auto todoToUpdate = todosInProgress[0];
95+
realm.write([&realm, &todoToUpdate] {
96+
todoToUpdate.status = "Complete";
97+
});
98+
// :snippet-end:
99+
CHECK(*todoToUpdate.status == "Complete");
100+
101+
// :snippet-start: delete
102+
realm.write([&realm, &todo] {
103+
realm.remove(todo);
104+
});
105+
// :snippet-end:
106+
}
107+
108+
TEST_CASE("sync quick start", "[realm][write][sync]") {
109+
// :snippet-start: connect-to-backend
110+
auto app = realm::App(APP_ID);
111+
// :snippet-end:
112+
113+
// :snippet-start: authenticate-user
114+
auto user = app.login(realm::App::credentials::anonymous()).get_future().get();
115+
// :snippet-end:
116+
117+
// :snippet-start: open-synced-realm
118+
auto sync_config = user.flexible_sync_configuration();
119+
auto synced_realm_ref = realm::async_open<Sync_Todo>(sync_config).get_future().get();
120+
auto realm = synced_realm_ref.resolve();
121+
// :remove-start:
122+
// Remove any existing subscriptions before adding the one for this example
123+
auto clearInitialSubscriptions = realm.subscriptions().update([](auto &subs) {
124+
subs.clear();
125+
}).get_future().get();
126+
CHECK(clearInitialSubscriptions == true);
127+
CHECK(realm.subscriptions().size() == 0);
128+
// :remove-end:
129+
// For this example, get the userId for the Flexible Sync query
130+
auto userId = user.identifier();
131+
auto subscriptions = realm.subscriptions();
132+
auto updateSubscriptionSuccess = subscriptions.update([&](realm::mutable_sync_subscription_set &subs) {
133+
subs.add<Sync_Todo>("todos", [&userId](auto &obj) {
134+
// For this example, get only Sync_Todo items where the ownerId
135+
// property value is equal to the userId of the logged-in user.
136+
return obj.ownerId == userId;
137+
});
138+
}).get_future().get();
139+
// :snippet-end:
140+
CHECK(updateSubscriptionSuccess == true);
141+
142+
// The C++ SDK is currently missing a constructor to store a std::string
143+
// So convert the userId std::string to a character array for persisting.
144+
// TODO: Remove this and use the userId directly when the constructor is added.
145+
// :snippet-start: write-to-synced-realm
146+
auto todo = Sync_Todo {
147+
.name = "Create a Sync todo item",
148+
.status = "In Progress",
149+
.ownerId = userId.c_str()
150+
};
151+
152+
realm.write([&realm, &todo] {
153+
realm.add(todo);
154+
});
155+
156+
auto todos = realm.objects<Sync_Todo>();
157+
// :snippet-end:
158+
CHECK(todos.size() == 1);
159+
160+
// The C++ SDK does not yet expose `waitForUpload` and `waitForDownload`
161+
// so add a delay to prevent the connection from terminating while syncing
162+
sleep(5);
163+
realm.write([&realm, &todo] {
164+
realm.remove(todo);
165+
});
166+
sleep(5);
167+
}
168+
169+
// :replace-end:

snooty.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ toc_landing_pages = [
1414
# SDKs
1515
"/sdk",
1616
"/sdk/cpp",
17+
"/sdk/cpp/application-services",
1718
"/sdk/cpp/manage-users",
1819
"/sdk/java",
1920
"/sdk/java/api",
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
auto user = app.login(realm::App::credentials::anonymous()).get_future().get();
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
auto app = realm::App(APP_ID);
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
auto todo = Todo {
2+
.name = "Create my first todo item",
3+
.status = "In Progress"
4+
};
5+
6+
realm.write([&realm, &todo] {
7+
realm.add(todo);
8+
});
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
realm.write([&realm, &todo] {
2+
realm.remove(todo);
3+
});
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
auto todosInProgress = todos.where([](auto const& todo) {
2+
return todo.status == "In Progress";
3+
});
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
auto todos = realm.objects<Todo>();
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#include <cpprealm/sdk.hpp>
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
struct Todo : realm::object<Todo> {
2+
realm::persisted<realm::object_id> _id{realm::object_id::generate()};
3+
realm::persisted<std::string> name;
4+
realm::persisted<std::string> status;
5+
// The ownerId property stores the user.identifier() of a
6+
// logged-in user. Omit this property for the non-sync example.
7+
realm::persisted<std::string> ownerId;
8+
9+
static constexpr auto schema = realm::schema("Todo",
10+
realm::property<&Todo::_id, true>("_id"),
11+
realm::property<&Todo::name>("name"),
12+
realm::property<&Todo::status>("status"),
13+
realm::property<&Todo::ownerId>("ownerId"));
14+
};
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
auto todoToUpdate = todosInProgress[0];
2+
realm.write([&realm, &todoToUpdate] {
3+
todoToUpdate.status = "Complete";
4+
});
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
auto sync_config = user.flexible_sync_configuration();
2+
auto synced_realm_ref = realm::async_open<Todo>(sync_config).get_future().get();
3+
auto realm = synced_realm_ref.resolve();
4+
// For this example, get the userId for the Flexible Sync query
5+
auto userId = user.identifier();
6+
auto subscriptions = realm.subscriptions();
7+
auto updateSubscriptionSuccess = subscriptions.update([&](realm::mutable_sync_subscription_set &subs) {
8+
subs.add<Todo>("todos", [&userId](auto &obj) {
9+
// For this example, get only Todo items where the ownerId
10+
// property value is equal to the userId of the logged-in user.
11+
return obj.ownerId == userId;
12+
});
13+
}).get_future().get();
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
auto realm = realm::open<Todo>();
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
auto token = todo.observe([&](auto&& change) {
2+
try {
3+
if (change.error) {
4+
rethrow_exception(change.error);
5+
}
6+
if (change.is_deleted) {
7+
std::cout << "The object was deleted.\n";
8+
} else {
9+
for (auto& propertyChange : change.property_changes) {
10+
std::cout << "The object's " << propertyChange.name << " property has changed.\n";
11+
}
12+
}
13+
} catch (std::exception const& e) {
14+
std::cerr << "Error: " << e.what() << "\n";
15+
}
16+
});
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
auto todo = Todo {
2+
.name = "Create a Sync todo item",
3+
.status = "In Progress",
4+
.ownerId = userId
5+
};
6+
7+
realm.write([&realm, &todo] {
8+
realm.add(todo);
9+
});
10+
11+
auto todos = realm.objects<Todo>();
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
.. note::
22

33
Flexible Sync does not support all the query operators available in Realm
4-
Query Language and LINQ. See :ref:`Flexible Sync RQL Limitations
5-
<flexible-sync-rql-limitations>` for details.
4+
Query Language and the SDK's query engine. See :ref:`Flexible Sync RQL
5+
Limitations <flexible-sync-rql-limitations>` for details.

source/sdk/cpp.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@ C++ SDK (Alpha)
99

1010
Why Realm Database? </sdk/cpp/realm-database>
1111
Install Realm </sdk/cpp/install>
12+
Quick Start </sdk/cpp/quick-start>
1213
Model Data </sdk/cpp/model-data>
1314
Configure & Open a Realm </sdk/cpp/realm-files/configure-and-open-a-realm>
1415
CRUD </sdk/cpp/crud/>
1516
React to Changes </sdk/cpp/react-to-changes>
16-
Connect to App Services </sdk/cpp/app-services/connect-to-app>
17+
Application Services </sdk/cpp/application-services>
1718
Manage Users </sdk/cpp/manage-users>
1819
Manage Sync Subscriptions </sdk/cpp/sync/sync-subscriptions>
19-
Call an Atlas Function </sdk/cpp/app-services/call-a-function>
2020
GitHub <https://github.com/realm/realm-cpp>
2121
API Reference (Doxygen) <https://www.mongodb.com/docs/realm-sdks/cpp/latest/>
2222

0 commit comments

Comments
 (0)