diff --git a/.github/workflows/examples.yaml b/.github/workflows/examples.yaml index 50c47d76bc..c53b2f1bb9 100644 --- a/.github/workflows/examples.yaml +++ b/.github/workflows/examples.yaml @@ -65,7 +65,7 @@ jobs: shell: bash run: | cd ../build - examples/basic_example/basic_example -e localhost:2136 -d /local -p /local/basic + examples/basic_example/basic_example -e localhost:2136 -d /local examples/bulk_upsert_simple/bulk_upsert_simple -e localhost:2136 -d /local -p /local/bulk examples/pagination/pagination -e localhost:2136 -d /local -p /local/pagination examples/ttl/ttl -e localhost:2136 -d /local -p /local/ttl diff --git a/examples/basic_example/basic_example.cpp b/examples/basic_example/basic_example.cpp index 5d3b901413..552a3d2cba 100644 --- a/examples/basic_example/basic_example.cpp +++ b/examples/basic_example/basic_example.cpp @@ -46,10 +46,10 @@ std::string OptionalToString(const std::optional& opt) /////////////////////////////////////////////////////////////////////////////// -static void CreateTables(TQueryClient client, const std::string& path) { - ThrowOnError(client.RetryQuerySync([path](TSession session) { - auto query = std::format(R"( - PRAGMA TablePathPrefix("{}"); +static void CreateTables(TQueryClient client) { + //! Creates sample tables with the ExecuteQuery method + ThrowOnError(client.RetryQuerySync([](TSession session) { + auto query = R"( CREATE TABLE series ( series_id Uint64, title Utf8, @@ -57,13 +57,12 @@ static void CreateTables(TQueryClient client, const std::string& path) { release_date Uint64, PRIMARY KEY (series_id) ); - )", path.c_str()); + )"; return session.ExecuteQuery(query, TTxControl::NoTx()).GetValueSync(); })); - ThrowOnError(client.RetryQuerySync([path](TSession session) { - auto query = std::format(R"( - PRAGMA TablePathPrefix("{}"); + ThrowOnError(client.RetryQuerySync([](TSession session) { + auto query = R"( CREATE TABLE seasons ( series_id Uint64, season_id Uint64, @@ -72,13 +71,12 @@ static void CreateTables(TQueryClient client, const std::string& path) { last_aired Uint64, PRIMARY KEY (series_id, season_id) ); - )", path.c_str()); + )"; return session.ExecuteQuery(query, TTxControl::NoTx()).GetValueSync(); })); - ThrowOnError(client.RetryQuerySync([path](TSession session) { - auto query = std::format(R"( - PRAGMA TablePathPrefix("{}"); + ThrowOnError(client.RetryQuerySync([](TSession session) { + auto query = R"( CREATE TABLE episodes ( series_id Uint64, season_id Uint64, @@ -87,46 +85,41 @@ static void CreateTables(TQueryClient client, const std::string& path) { air_date Uint64, PRIMARY KEY (series_id, season_id, episode_id) ); - )", path.c_str()); + )"; return session.ExecuteQuery(query, TTxControl::NoTx()).GetValueSync(); })); } /////////////////////////////////////////////////////////////////////////////// -static void DropTables(TQueryClient client, const std::string& path) { - ThrowOnError(client.RetryQuerySync([path](TSession session) { - auto query = std::format(R"( - PRAGMA TablePathPrefix("{}"); +static void DropTables(TQueryClient client) { + ThrowOnError(client.RetryQuerySync([](TSession session) { + auto query = R"( DROP TABLE series; - )", path.c_str()); + )"; return session.ExecuteQuery(query, TTxControl::NoTx()).GetValueSync(); })); - ThrowOnError(client.RetryQuerySync([path](TSession session) { - auto query = std::format(R"( - PRAGMA TablePathPrefix("{}"); + ThrowOnError(client.RetryQuerySync([](TSession session) { + auto query = R"( DROP TABLE seasons; - )", path.c_str()); + )"; return session.ExecuteQuery(query, TTxControl::NoTx()).GetValueSync(); })); - ThrowOnError(client.RetryQuerySync([path](TSession session) { - auto query = std::format(R"( - PRAGMA TablePathPrefix("{}"); + ThrowOnError(client.RetryQuerySync([](TSession session) { + auto query = R"( DROP TABLE episodes; - )", path.c_str()); + )"; return session.ExecuteQuery(query, TTxControl::NoTx()).GetValueSync(); })); } /////////////////////////////////////////////////////////////////////////////// -void FillTableData(TQueryClient client, const std::string& path) { - ThrowOnError(client.RetryQuerySync([path](TSession session) { - auto query = std::format(R"( - PRAGMA TablePathPrefix("{}"); - +void FillTableData(TQueryClient client) { + ThrowOnError(client.RetryQuerySync([](TSession session) { + auto query = R"( DECLARE $seriesData AS List resultSet; - ThrowOnError(client.RetryQuerySync([&path, &resultSet](TSession session) { - auto query = std::format(R"( - PRAGMA TablePathPrefix("{}"); - - SELECT series_id, title, CAST(CAST(release_date AS Date) AS String) AS release_date + ThrowOnError(client.RetryQuerySync([&resultSet](TSession session) { + auto query = R"( + SELECT series_id, title, CAST(release_date AS Date) AS release_date FROM series WHERE series_id = 1; - )", path.c_str()); + )"; auto txControl = - // Begin new transaction with SerializableRW mode + // Begin a new transaction with SerializableRW mode TTxControl::BeginTx(TTxSettings::SerializableRW()) - // Commit transaction at the end of the query + // Commit the transaction at the end of the query .CommitTx(); auto result = session.ExecuteQuery(query, txControl).GetValueSync(); @@ -209,39 +200,33 @@ void SelectSimple(TQueryClient client, const std::string& path) { })); TResultSetParser parser(*resultSet); - if (parser.TryNextRow()) { + while (parser.TryNextRow()) { std::cout << "> SelectSimple:" << std::endl << "Series" - << ", Id: " << OptionalToString(parser.ColumnParser("series_id").GetOptionalUint64()) - << ", Title: " << OptionalToString(parser.ColumnParser("title").GetOptionalUtf8()) - << ", Release date: " << OptionalToString(parser.ColumnParser("release_date").GetOptionalString()) - << std::endl; + << ", Id: " << OptionalToString(parser.ColumnParser("series_id").GetOptionalUint64()) + << ", Title: " << OptionalToString(parser.ColumnParser("title").GetOptionalUtf8()) + << ", Release date: " << parser.ColumnParser("release_date").GetOptionalDate()->FormatLocalTime("%Y-%m-%d") + << std::endl; } } -void UpsertSimple(TQueryClient client, const std::string& path) { - ThrowOnError(client.RetryQuerySync([path](TSession session) { - auto query = std::format(R"( - --!syntax_v1 - PRAGMA TablePathPrefix("{}"); - +void UpsertSimple(TQueryClient client) { + ThrowOnError(client.RetryQuerySync([](TSession session) { + auto query = R"( UPSERT INTO episodes (series_id, season_id, episode_id, title) VALUES (2, 6, 1, "TBD"); - )", path.c_str()); + )"; return session.ExecuteQuery(query, TTxControl::BeginTx(TTxSettings::SerializableRW()).CommitTx()).GetValueSync(); })); } -void SelectWithParams(TQueryClient client, const std::string& path) { +void SelectWithParams(TQueryClient client) { std::optional resultSet; - ThrowOnError(client.RetryQuerySync([&path, &resultSet](TSession session) { + ThrowOnError(client.RetryQuerySync([&resultSet](TSession session) { ui64 seriesId = 2; ui64 seasonId = 3; - auto query = std::format(R"( - --!syntax_v1 - PRAGMA TablePathPrefix("{}"); - + auto query = R"( DECLARE $seriesId AS Uint64; DECLARE $seasonId AS Uint64; @@ -250,7 +235,7 @@ void SelectWithParams(TQueryClient client, const std::string& path) { INNER JOIN series AS sr ON sa.series_id = sr.series_id WHERE sa.series_id = $seriesId AND sa.season_id = $seasonId; - )", path.c_str()); + )"; auto params = TParamsBuilder() .AddParam("$seriesId") @@ -276,27 +261,24 @@ void SelectWithParams(TQueryClient client, const std::string& path) { TResultSetParser parser(*resultSet); if (parser.TryNextRow()) { std::cout << "> SelectWithParams:" << std::endl << "Season" - << ", Title: " << OptionalToString(parser.ColumnParser("season_title").GetOptionalUtf8()) - << ", Series title: " << OptionalToString(parser.ColumnParser("series_title").GetOptionalUtf8()) - << std::endl; + << ", Title: " << OptionalToString(parser.ColumnParser("season_title").GetOptionalUtf8()) + << ", Series title: " << OptionalToString(parser.ColumnParser("series_title").GetOptionalUtf8()) + << std::endl; } } -void MultiStep(TQueryClient client, const std::string& path) { - std::optional resultSet; - ThrowOnError(client.RetryQuerySync([&path, &resultSet](TSession session) { +void MultiStep(TQueryClient client) { + TMaybe resultSet; + ThrowOnError(client.RetryQuerySync([&resultSet](TSession session) { ui64 seriesId = 2; ui64 seasonId = 5; - auto query1 = std::format(R"( - --!syntax_v1 - PRAGMA TablePathPrefix("{}"); - + auto query1 = R"( DECLARE $seriesId AS Uint64; DECLARE $seasonId AS Uint64; SELECT first_aired AS from_date FROM seasons WHERE series_id = $seriesId AND season_id = $seasonId; - )", path.c_str()); + )"; auto params1 = TParamsBuilder() .AddParam("$seriesId") @@ -307,8 +289,8 @@ void MultiStep(TQueryClient client, const std::string& path) { .Build() .Build(); - // Execute first query to get the required values to the client. - // Transaction control settings don't set CommitTx flag to keep transaction active + // Execute the first query to retrieve the required values for the client. + // Transaction control settings do not set the CommitTx flag, allowing the transaction to remain active // after query execution. auto result = session.ExecuteQuery( query1, @@ -321,9 +303,10 @@ void MultiStep(TQueryClient client, const std::string& path) { return resultValue; } - // Get active transaction id - auto tx = resultValue.GetTransaction(); - + // Get the active transaction id + auto txId = resultValue.GetTransaction()->GetId(); + + // Processing the request result TResultSetParser parser(resultValue.GetResultSet(0)); parser.TryNextRow(); auto date = parser.ColumnParser("from_date").GetOptionalUint64(); @@ -337,17 +320,14 @@ void MultiStep(TQueryClient client, const std::string& path) { TInstant toDate = userFunc(fromDate); // Construct next query based on the results of client logic - auto query2 = std::format(R"( - --!syntax_v1 - PRAGMA TablePathPrefix("{}"); - + auto query2 = R"( DECLARE $seriesId AS Uint64; DECLARE $fromDate AS Uint64; DECLARE $toDate AS Uint64; SELECT season_id, episode_id, title, air_date FROM episodes WHERE series_id = $seriesId AND air_date >= $fromDate AND air_date <= $toDate; - )", path.c_str()); + )"; auto params2 = TParamsBuilder() .AddParam("$seriesId") @@ -361,12 +341,12 @@ void MultiStep(TQueryClient client, const std::string& path) { .Build() .Build(); - // Execute second query. - // Transaction control settings continues active transaction (tx) and - // commits it at the end of second query execution. + // Execute the second query. + // The transaction control settings continue the active transaction (tx) + // and commit it at the end of the second query execution. auto result2 = session.ExecuteQuery( query2, - TTxControl::Tx(tx->GetId()).CommitTx(), + TTxControl::Tx(txId).CommitTx(), params2).GetValueSync(); if (!result2.IsSuccess()) { @@ -374,7 +354,7 @@ void MultiStep(TQueryClient client, const std::string& path) { } resultSet = result2.GetResultSet(0); return result2; - })); + })); // The end of the retried lambda TResultSetParser parser(*resultSet); std::cout << "> MultiStep:" << std::endl; @@ -382,18 +362,18 @@ void MultiStep(TQueryClient client, const std::string& path) { auto airDate = TInstant::Days(*parser.ColumnParser("air_date").GetOptionalUint64()); std::cout << "Episode " << OptionalToString(parser.ColumnParser("episode_id").GetOptionalUint64()) - << ", Season: " << OptionalToString(parser.ColumnParser("season_id").GetOptionalUint64()) - << ", Title: " << OptionalToString(parser.ColumnParser("title").GetOptionalUtf8()) - << ", Air date: " << airDate.FormatLocalTime("%a %b %d, %Y") - << std::endl; + << ", Season: " << OptionalToString(parser.ColumnParser("season_id").GetOptionalUint64()) + << ", Title: " << OptionalToString(parser.ColumnParser("title").GetOptionalUtf8()) + << ", Air date: " << airDate.FormatLocalTime("%a %b %d, %Y") + << std::endl; } } -void ExplicitTcl(TQueryClient client, const std::string& path) { - // Show usage of explicit Begin/Commit transaction control calls. - // In most cases it's better to use transaction control settings in ExecuteDataQuery calls instead - // to avoid additional hops to YDB cluster and allow more efficient execution of queries. - ThrowOnError(client.RetryQuerySync([&path](TQueryClient client) -> TStatus { +void ExplicitTcl(TQueryClient client) { + // Demonstrate the use of explicit Begin and Commit transaction control calls. + // In most cases, it's preferable to use transaction control settings within ExecuteDataQuery calls instead, + // as this avoids additional hops to the YDB cluster and allows for more efficient query execution. + ThrowOnError(client.RetryQuerySync([](TQueryClient client) -> TStatus { auto airDate = TInstant::Now(); auto session = client.GetSession().GetValueSync().GetSession(); auto beginResult = session.BeginTransaction(TTxSettings::SerializableRW()).GetValueSync(); @@ -404,14 +384,11 @@ void ExplicitTcl(TQueryClient client, const std::string& path) { // Get newly created transaction id auto tx = beginResult.GetTransaction(); - auto query = std::format(R"( - --!syntax_v1 - PRAGMA TablePathPrefix("{}"); - + auto query = R"( DECLARE $airDate AS Date; UPDATE episodes SET air_date = CAST($airDate AS Uint16) WHERE title = "TBD"; - )", path.c_str()); + )"; auto params = TParamsBuilder() .AddParam("$airDate") @@ -433,30 +410,32 @@ void ExplicitTcl(TQueryClient client, const std::string& path) { })); } -void StreamQuerySelect(TQueryClient client, const std::string& path) { - std::vector resultSets; - // WARNING: Do not use without RetryQuery!!! - ThrowOnError(client.RetryQuerySync([path, &resultSets](TQueryClient client) -> TStatus { - resultSets.clear(); - auto query = std::format(R"( - --!syntax_v1 - PRAGMA TablePathPrefix("{}"); +void StreamQuerySelect(TQueryClient client) { + std::cout << "> StreamQuery:" << std::endl; + ThrowOnError(client.RetryQuerySync([](TQueryClient client) -> TStatus { + auto query = R"( DECLARE $series AS List; - SELECT series_id, season_id, title, CAST(CAST(first_aired AS Date) AS String) AS first_aired + SELECT series_id, season_id, title, CAST(first_aired AS Date) AS first_aired FROM seasons WHERE series_id IN $series ORDER BY season_id; - )", path.c_str()); - - auto parameters = TParamsBuilder() - .AddParam("$series") - .BeginList() - .AddListItem().Uint64(1) - .AddListItem().Uint64(10) - .EndList().Build() - .Build(); + )"; + + auto paramsBuilder = TParamsBuilder(); + auto& listParams = paramsBuilder + .AddParam("$series") + .BeginList(); + + for (auto x : {1, 10}) { + listParams.AddListItem().Uint64(x); + } + + auto parameters = listParams + .EndList() + .Build() + .Build(); // Executes stream query auto resultStreamQuery = client.StreamExecuteQuery(query, TTxControl::NoTx(), parameters).GetValueSync(); @@ -465,6 +444,7 @@ void StreamQuerySelect(TQueryClient client, const std::string& path) { return resultStreamQuery; } + // Iterates over results bool eos = false; while (!eos) { @@ -478,51 +458,48 @@ void StreamQuerySelect(TQueryClient client, const std::string& path) { continue; } + // It is possible to duplicate lines in the output stream due to an external retryer. if (streamPart.HasResultSet()) { auto rs = streamPart.ExtractResultSet(); - resultSets.push_back(rs); + TResultSetParser parser(rs); + while (parser.TryNextRow()) { + std::cout << "Season" + << ", SeriesId: " << OptionalToString(parser.ColumnParser("series_id").GetOptionalUint64()) + << ", SeasonId: " << OptionalToString(parser.ColumnParser("season_id").GetOptionalUint64()) + << ", Title: " << OptionalToString(parser.ColumnParser("title").GetOptionalUtf8()) + << ", Air date: " << parser.ColumnParser("first_aired").GetOptionalDate()->FormatLocalTime("%Y-%m-%d") + << std::endl; + } } } return TStatus(EStatus::SUCCESS, NYql::TIssues()); })); - - std::cout << "> StreamQuery:" << std::endl; - for (auto rs : resultSets) { - TResultSetParser parser(rs); - while (parser.TryNextRow()) { - std::cout << "Season" - << ", SeriesId: " << OptionalToString(parser.ColumnParser("series_id").GetOptionalUint64()) - << ", SeasonId: " << OptionalToString(parser.ColumnParser("season_id").GetOptionalUint64()) - << ", Title: " << OptionalToString(parser.ColumnParser("title").GetOptionalUtf8()) - << ", Air date: " << OptionalToString(parser.ColumnParser("first_aired").GetOptionalString()) - << std::endl; - } - } + } /////////////////////////////////////////////////////////////////////////////// -bool Run(const TDriver& driver, const std::string& path) { +bool Run(const TDriver& driver) { TQueryClient client(driver); try { - CreateTables(client, path); + CreateTables(client); - FillTableData(client, path); + FillTableData(client); - SelectSimple(client, path); - UpsertSimple(client, path); + SelectSimple(client); + UpsertSimple(client); - SelectWithParams(client, path); + SelectWithParams(client); - MultiStep(client, path); + MultiStep(client); - ExplicitTcl(client, path); + ExplicitTcl(client); - StreamQuerySelect(client, path); + StreamQuerySelect(client); - DropTables(client, path); + DropTables(client); } catch (const TYdbErrorException& e) { std::cerr << "Execution failed due to fatal error:" << std::endl; diff --git a/examples/basic_example/basic_example.h b/examples/basic_example/basic_example.h index 63c557cd66..04260a5f29 100644 --- a/examples/basic_example/basic_example.h +++ b/examples/basic_example/basic_example.h @@ -8,4 +8,4 @@ NYdb::TParams GetTablesDataParams(); -bool Run(const NYdb::TDriver& driver, const std::string& path); +bool Run(const NYdb::TDriver& driver); diff --git a/examples/basic_example/main.cpp b/examples/basic_example/main.cpp index 86320b12a4..5bc2571762 100644 --- a/examples/basic_example/main.cpp +++ b/examples/basic_example/main.cpp @@ -24,15 +24,12 @@ int main(int argc, char** argv) { std::string endpoint; std::string database; - std::string path; std::string certPath; opts.AddLongOption('e', "endpoint", "YDB endpoint").Required().RequiredArgument("HOST:PORT") .StoreResult(&endpoint); opts.AddLongOption('d', "database", "YDB database name").Required().RequiredArgument("PATH") .StoreResult(&database); - opts.AddLongOption('p', "path", "Base path for tables").Optional().RequiredArgument("PATH") - .StoreResult(&path); opts.AddLongOption('c', "cert", "Certificate path to use secure connection").Optional().RequiredArgument("PATH") .StoreResult(&certPath); @@ -41,10 +38,6 @@ int main(int argc, char** argv) { TOptsParseResult res(&opts, argc, argv); - if (path.empty()) { - path = database; - } - auto driverConfig = TDriverConfig() .SetEndpoint(endpoint) .SetDatabase(database) @@ -57,7 +50,7 @@ int main(int argc, char** argv) { TDriver driver(driverConfig); - if (!Run(driver, path)) { + if (!Run(driver)) { driver.Stop(true); return 2; }