Stroika Library 3.0d23
 
Loading...
Searching...
No Matches
Samples/DocumentDB/Sources/Main.cpp
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2026. All rights reserved
3 */
4#include "Stroika/Frameworks/StroikaPreComp.h"
5
6#include <cstdlib>
7#include <iostream>
8
10#include "Stroika/Foundation/Database/Document/MongoDBClient.h"
13#include "Stroika/Foundation/Execution/CommandLine.h"
14#include "Stroika/Foundation/Execution/Module.h"
17
18#include "ComputerNetwork.h"
19#include "EmployeesDB.h"
20
21using namespace std;
22
23using namespace Stroika::Foundation;
25using namespace Stroika::Foundation::Database;
26using namespace Stroika::Foundation::Execution;
27
28int main ([[maybe_unused]] int argc, [[maybe_unused]] const char* argv[])
29{
30 using namespace Database::Document;
31
32 using namespace Stroika::Samples::Document;
33
34#if qStroika_HasComponent_mongocxxdriver
35 optional<String> mongoConnectionString;
36#endif
37
38 // handle command-line arguments
39 {
40 using namespace StandardCommandLineOptions;
41 const CommandLine::Option kMongoConnectionStringOption_{
42 .fLongName = "mongoConnectionString"sv,
43 .fSupportsArgument = true,
44 .fHelpOptionText = "Connect to this mongo database for testing, eg: mongodb://admin:pass@localhost:27017; OR ENV VAR MONGO_CONNECTION_STRING"sv};
45
46 const initializer_list<CommandLine::Option> kAllOptions_{kHelp,
47#if qStroika_HasComponent_mongocxxdriver
48 kMongoConnectionStringOption_
49#endif
50 };
51
52 CommandLine cmdLine{argc, argv};
53 if (cmdLine.Has (kHelp)) {
54 cerr << CommandLine::GenerateUsage ("documentDB", kAllOptions_);
55 return EXIT_SUCCESS;
56 }
57 if (auto error = cmdLine.ValidateQuietly (kAllOptions_)) {
58 cerr << "{}"_f(*error) << endl;
59 cerr << CommandLine::GenerateUsage ("myApp", kAllOptions_) << endl;
60 }
61#if qStroika_HasComponent_mongocxxdriver
62 mongoConnectionString = Memory::Or_Else (cmdLine.GetArgument (kMongoConnectionStringOption_),
63 [] () { return kEnvironment->Lookup ("MONGO_CONNECTION_STRING"sv); });
64#endif
65 }
66
67#if qStroika_HasComponent_mongocxxdriver
68 Database::Document::MongoDBClient::Activator activator{}; // must exist while using mongocxxclient library
69#endif
70
71#if qStroika_HasComponent_mongocxxdriver
72 if (not mongoConnectionString) {
73 cerr << "Warning: skipping mongodb test because no connection string specified on command-line nor environment variable" << endl;
74 }
75 if (mongoConnectionString) {
76 using namespace Stroika::Foundation::Database::Document::MongoDBClient;
77 const String kTestDBName_ = "DocumentDB-Sample-Networks"sv;
78 try {
79 static const Activity kActivity_{"performing MongoDBClient test on {}"_f(kTestDBName_)};
80 DeclareActivity da{&kActivity_};
81 auto adminDB = AdminConnection::New (AdminConnection::Options{.fConnectionTarget = *mongoConnectionString});
82 IgnoreExceptionsForCall (adminDB.DropDatabase (kTestDBName_));
83 adminDB.CreateDatabase (kTestDBName_);
84 cerr << "Starting MongoDBClient networks sample:" << endl;
85 ComputerNetworksModel ([=] () {
86 // can create a new connection each time
87 cerr << "\tConnecting to {} database {}"_f(*mongoConnectionString, kTestDBName_) << endl;
88 return MongoDBClient::Connection::New (
89 MongoDBClient::Connection::Options{.fConnectionTarget = *mongoConnectionString, .fDatabase = kTestDBName_});
90 });
91 cerr << "done." << endl;
92 }
93 catch (...) {
94 cerr << "\t{}"_f(current_exception ()) << endl;
95 }
96 }
97 if (mongoConnectionString) {
98 using namespace Stroika::Foundation::Database::Document::MongoDBClient;
99 const String kTestDBName_ = "DocumentDB-Sample-Employees"sv;
100 try {
101 static const Activity kActivity_{"performing MongoDBClient test on {}"_f(kTestDBName_)};
102 DeclareActivity da{&kActivity_};
103 auto adminDB = AdminConnection::New (AdminConnection::Options{.fConnectionTarget = *mongoConnectionString});
104 IgnoreExceptionsForCall (adminDB.DropDatabase (kTestDBName_));
105 adminDB.CreateDatabase (kTestDBName_);
106 Database::Document::Connection::Ptr internallySyncrhonizedConnection = MongoDBClient::Connection::New (MongoDBClient::Connection::Options{
107 .fInternallySynchronizedLetter = eInternallySynchronized, .fConnectionTarget = *mongoConnectionString, .fDatabase = kTestDBName_});
108 cerr << "Starting mongodb employees sample:" << endl;
109 EmployeesDB ([=] () {
110 cerr << "\tConnecting to {} database {}"_f(*mongoConnectionString, kTestDBName_) << endl;
111 return internallySyncrhonizedConnection; // each thread using same internally syncrhonized connection
112 // or can create a new connection each time in factory, and make them unsynchronized
113 });
114 cerr << "done." << endl;
115 }
116 catch (...) {
117 cerr << "\t{}"_f(current_exception ()) << endl;
118 }
119 }
120#endif
121
122#if qStroika_HasComponent_sqlite
123 // quick tests with in-memory DB
124 try {
125 const String kTestDBName_ = "DocumentDB-Sample-Networks"sv;
126 static const Activity kActivity_{"performing sqlite document db networks sample on {}"_f(kTestDBName_)};
127 DeclareActivity da{&kActivity_};
128 cerr << "Starting sqlite document db networks sample:" << endl;
129 ComputerNetworksModel ([=] () {
130 cerr << "\tConnecting to sqlite memory db: {}"_f(kTestDBName_) << endl;
131 return SQLite::Connection::New (SQLite::Connection::Options{.fInMemoryDB = kTestDBName_});
132 });
133 cerr << "done." << endl;
134 }
135 catch (...) {
136 cerr << "\t{}"_f(current_exception ()) << endl;
137 }
138 try {
139 const String kTestDBName_ = "DocumentDB-Sample-Employees"sv;
140 static const Activity kActivity_{"performing sqlite document db employees sample on {}"_f(kTestDBName_)};
141 DeclareActivity da{&kActivity_};
142 cerr << "Starting sqlite document db employees sample on memory db {}"_f(kTestDBName_) << endl;
143 EmployeesDB ([=] () {
144 cerr << "\tConnecting to sqlite memory db: {}"_f(kTestDBName_) << endl;
145 return SQLite::Connection::New (SQLite::Connection::Options{.fInMemoryDB = kTestDBName_});
146 });
147 cerr << "done." << endl;
148 }
149 catch (...) {
150 cerr << "\t{}"_f(current_exception ()) << endl;
151 }
152 // or run same test on filesystem
153 try {
154 auto dbPath = IO::FileSystem::WellKnownLocations::GetTemporary () / "networks-test.db";
155 static const Activity kActivity_{"performing sqlite document db networks sample on {}"_f(dbPath)};
156 DeclareActivity da{&kActivity_};
157 remove (dbPath); // test assumes empty db
158 cerr << "Starting sqlite document db networks sample:" << endl;
159 ComputerNetworksModel ([=] () {
160 cerr << "\tConnecting to sqlite db: {}"_f(dbPath) << endl;
161 return SQLite::Connection::New (SQLite::Connection::Options{.fDBPath = dbPath});
162 });
163 cerr << "done." << endl;
164 }
165 catch (...) {
166 cerr << "\t{}"_f(current_exception ()) << endl;
167 }
168 try {
169 auto dbPath = IO::FileSystem::WellKnownLocations::GetTemporary () / "employees-test.db";
170 static const Activity kActivity_{"performing Starting sqlite document db employees sample on {}"_f(dbPath)};
171 DeclareActivity da{&kActivity_};
172 remove (dbPath); // test assumes empty db
173 cerr << "Starting sqlite document db employees sample on {}"_f(dbPath) << endl;
174 EmployeesDB ([=] () {
175 cerr << "\tConnecting to sqlite db: {}"_f(dbPath) << endl;
176 auto c = SQLite::Connection::New (SQLite::Connection::Options{.fDBPath = dbPath});
177 return c;
178 });
179 cerr << "done." << endl;
180 }
181 catch (...) {
182 cerr << "\t{}"_f(current_exception ()) << endl;
183 }
184#endif
185 // Try LocalDocumentDB
186 try {
187 static constexpr Activity kActivity_{"performing trivial document db networks sample"sv};
188 DeclareActivity da{&kActivity_};
189 cerr << "Starting trivial document db networks sample:" << endl;
190 auto internallySynchronizedDBConnection = LocalDocumentDB::New (LocalDocumentDB::Options{
191 .fInternallySynchronizedLetter = eInternallySynchronized, .fStorage = LocalDocumentDB::Options::MemoryStorage{}});
192 ComputerNetworksModel ([=] () {
193 cerr << "\tConnecting to trivial document db: memory" << endl;
194 return internallySynchronizedDBConnection; // re-used multiple times from different threads
195 });
196 cerr << "done." << endl;
197 }
198 catch (...) {
199 cerr << "\t{}"_f(current_exception ()) << endl;
200 }
201 try {
202 static constexpr Activity kActivity_{"performing trivial document db employees sample"sv};
203 DeclareActivity da{&kActivity_};
204 cerr << "Starting trivial document db employees sample:" << endl;
205 auto internallySynchronizedDBConnection = LocalDocumentDB::New (LocalDocumentDB::Options{
206 .fInternallySynchronizedLetter = eInternallySynchronized, .fStorage = LocalDocumentDB::Options::MemoryStorage{}});
207 EmployeesDB ([=] () {
208 cerr << "\tConnecting to trivial document db: memory" << endl;
209 return internallySynchronizedDBConnection; // re-used multiple times from different threads
210 });
211 cerr << "done." << endl;
212 }
213 catch (...) {
214 cerr << "\t{}"_f(current_exception ()) << endl;
215 }
216 try {
217 static constexpr Activity kActivity_{"performing trivial document db employees sample"sv};
218 DeclareActivity da{&kActivity_};
219 cerr << "Starting trivial document db employees sample:" << endl;
220 filesystem::path p = IO::FileSystem::WellKnownLocations::GetTemporary () / "employees-trivialdb-test.json";
221 auto internallySynchronizedDBConnection = LocalDocumentDB::New (LocalDocumentDB::Options{
222 .fInternallySynchronizedLetter = eInternallySynchronized, .fStorage = LocalDocumentDB::Options::SingleFileStorage{.fFile = p}});
223 EmployeesDB ([=] () {
224 cerr << "\tConnecting to trivial document db: {}"_f(p) << endl;
225 return internallySynchronizedDBConnection; // re-used multiple times from different threads
226 });
227 cerr << "done." << endl;
228 }
229 catch (...) {
230 cerr << "\t{}"_f(current_exception ()) << endl;
231 }
232 try {
233 static constexpr Activity kActivity_{"performing trivial document db employees sample"sv};
234 DeclareActivity da{&kActivity_};
235 cerr << "Starting trivial document db employees sample:" << endl;
236 filesystem::path p = IO::FileSystem::WellKnownLocations::GetTemporary () / "employees-trivialdb-dir-test";
237 auto internallySynchronizedDBConnection = LocalDocumentDB::New (LocalDocumentDB::Options{
238 .fInternallySynchronizedLetter = eInternallySynchronized, .fStorage = LocalDocumentDB::Options::DirectoryFileStorage{.fRoot = p}});
239 EmployeesDB ([=] () {
240 cerr << "\tConnecting to trivial document db: {}"_f(p) << endl;
241 return internallySynchronizedDBConnection; // re-used multiple times from different threads
242 });
243 cerr << "done." << endl;
244 }
245 catch (...) {
246 cerr << "\t{}"_f(current_exception ()) << endl;
247 }
248
249 return EXIT_SUCCESS;
250}
String is like std::u32string, except it is much easier to use, often much more space efficient,...
Definition String.h:201
STL namespace.
Execution::InternallySynchronized fInternallySynchronizedLetter
use eInternallySynchronized to make letter internally synchronized