|
30 | 30 | #include "google/cloud/spanner/testing/random_backup_name.h" |
31 | 31 | #include "google/cloud/spanner/testing/random_database_name.h" |
32 | 32 | #include "google/cloud/spanner/testing/random_instance_name.h" |
| 33 | +#include "google/cloud/spanner/testing/singer.pb.h" |
33 | 34 | #include "google/cloud/spanner/update_instance_request_builder.h" |
34 | 35 | #include "google/cloud/internal/getenv.h" |
35 | 36 | #include "google/cloud/internal/random.h" |
@@ -989,6 +990,22 @@ void AddTimestampColumn( |
989 | 990 | } |
990 | 991 | // [END spanner_add_timestamp_column] |
991 | 992 |
|
| 993 | +//! [drop-column] |
| 994 | +void DropColumn(google::cloud::spanner_admin::DatabaseAdminClient client, |
| 995 | + std::string const& project_id, std::string const& instance_id, |
| 996 | + std::string const& database_id) { |
| 997 | + google::cloud::spanner::Database database(project_id, instance_id, |
| 998 | + database_id); |
| 999 | + auto metadata = |
| 1000 | + client |
| 1001 | + .UpdateDatabaseDdl(database.FullName(), |
| 1002 | + {"ALTER TABLE Singers DROP COLUMN SingerInfo"}) |
| 1003 | + .get(); |
| 1004 | + if (!metadata) throw std::move(metadata).status(); |
| 1005 | + std::cout << "Dropped SingerInfo column\n"; |
| 1006 | +} |
| 1007 | +//! [drop-column] |
| 1008 | + |
992 | 1009 | // [START spanner_create_storing_index] |
993 | 1010 | void AddStoringIndex(google::cloud::spanner_admin::DatabaseAdminClient client, |
994 | 1011 | std::string const& project_id, |
@@ -3649,6 +3666,250 @@ void DropForeignKeyConstraintDeleteCascade( |
3649 | 3666 | } |
3650 | 3667 | // [END spanner_drop_foreign_key_constraint_delete_cascade] |
3651 | 3668 |
|
| 3669 | +// [START spanner_add_proto_type_columns] |
| 3670 | +void AddProtoTypeColumns( |
| 3671 | + google::cloud::spanner_admin::DatabaseAdminClient client, |
| 3672 | + std::string const& project_id, std::string const& instance_id, |
| 3673 | + std::string const& database_id) { |
| 3674 | + google::cloud::spanner::Database database(project_id, instance_id, |
| 3675 | + database_id); |
| 3676 | + google::spanner::admin::database::v1::UpdateDatabaseDdlRequest request; |
| 3677 | + request.set_database(database.FullName()); |
| 3678 | + google::protobuf::FileDescriptorSet fds; |
| 3679 | + google::cloud::spanner::testing::SingerInfo::default_instance() |
| 3680 | + .GetMetadata() |
| 3681 | + .descriptor->file() |
| 3682 | + ->CopyTo(fds.add_file()); |
| 3683 | + fds.SerializeToString(request.mutable_proto_descriptors()); |
| 3684 | + request.add_statements(R"""( |
| 3685 | + CREATE PROTO BUNDLE ( |
| 3686 | + google.cloud.spanner.testing.SingerInfo, |
| 3687 | + google.cloud.spanner.testing.Genre, |
| 3688 | + ) |
| 3689 | + )"""); |
| 3690 | + request.add_statements(R"""( |
| 3691 | + ALTER TABLE Singers ADD COLUMN |
| 3692 | + SingerInfo google.cloud.spanner.testing.SingerInfo |
| 3693 | + )"""); |
| 3694 | + request.add_statements(R"""( |
| 3695 | + ALTER TABLE Singers ADD COLUMN |
| 3696 | + SingerInfoArray ARRAY<google.cloud.spanner.testing.SingerInfo> |
| 3697 | + )"""); |
| 3698 | + request.add_statements(R"""( |
| 3699 | + ALTER TABLE Singers ADD COLUMN |
| 3700 | + SingerGenre google.cloud.spanner.testing.Genre |
| 3701 | + )"""); |
| 3702 | + request.add_statements(R"""( |
| 3703 | + ALTER TABLE Singers ADD COLUMN |
| 3704 | + SingerGenreArray ARRAY<google.cloud.spanner.testing.Genre> |
| 3705 | + )"""); |
| 3706 | + auto metadata = client.UpdateDatabaseDdl(request).get(); |
| 3707 | + if (!metadata) throw std::move(metadata).status(); |
| 3708 | + std::cout << "`Singers` table altered, new DDL:\n" << metadata->DebugString(); |
| 3709 | +} |
| 3710 | +// [END spanner_add_proto_type_columns] |
| 3711 | + |
| 3712 | +// [START spanner_update_data_with_proto_message_column] |
| 3713 | +void UpdateDataWithProtoMessageColumn(google::cloud::spanner::Client client) { |
| 3714 | + google::cloud::spanner::testing::SingerInfo singer_proto; |
| 3715 | + singer_proto.set_singer_id(2); |
| 3716 | + singer_proto.set_birth_date("1942-06-18"); |
| 3717 | + singer_proto.set_nationality("British"); |
| 3718 | + singer_proto.set_genre(google::cloud::spanner::testing::Genre::POP); |
| 3719 | + |
| 3720 | + using SingerInfoMessage = google::cloud::spanner::ProtoMessage< |
| 3721 | + google::cloud::spanner::testing::SingerInfo>; |
| 3722 | + auto singer_info = SingerInfoMessage(singer_proto); |
| 3723 | + auto commit_results = |
| 3724 | + client.CommitAtLeastOnce({google::cloud::spanner::Mutations{ |
| 3725 | + google::cloud::spanner::InsertOrUpdateMutationBuilder( |
| 3726 | + "Singers", {"SingerId", "SingerInfo", "SingerInfoArray"}) |
| 3727 | + .EmplaceRow(2, singer_info, |
| 3728 | + std::vector<SingerInfoMessage>{singer_info}) |
| 3729 | + .EmplaceRow(3, absl::optional<SingerInfoMessage>(), |
| 3730 | + absl::optional<std::vector<SingerInfoMessage>>()) |
| 3731 | + .Build()}}); |
| 3732 | + for (auto& commit_result : commit_results) { |
| 3733 | + if (!commit_result) throw std::move(commit_result).status(); |
| 3734 | + } |
| 3735 | + std::cout << "Update was successful " |
| 3736 | + << "[spanner_update_data_with_proto_message_column]\n"; |
| 3737 | +} |
| 3738 | +// [END spanner_update_data_with_proto_message_column] |
| 3739 | + |
| 3740 | +// [START spanner_update_data_with_proto_message_column_with_dml] |
| 3741 | +void UpdateDataWithProtoMessageColumnWithDml( |
| 3742 | + google::cloud::spanner::Client client) { |
| 3743 | + std::int64_t rows_modified = 0; |
| 3744 | + auto commit_result = client.Commit( |
| 3745 | + [&client, &rows_modified](google::cloud::spanner::Transaction txn) |
| 3746 | + -> google::cloud::StatusOr<google::cloud::spanner::Mutations> { |
| 3747 | + google::cloud::spanner::testing::SingerInfo singer_proto; |
| 3748 | + singer_proto.set_singer_id(1); |
| 3749 | + singer_proto.set_birth_date("1943-06-15"); |
| 3750 | + singer_proto.set_nationality("French"); |
| 3751 | + singer_proto.set_genre(google::cloud::spanner::testing::Genre::ROCK); |
| 3752 | + |
| 3753 | + using SingerInfoMessage = google::cloud::spanner::ProtoMessage< |
| 3754 | + google::cloud::spanner::testing::SingerInfo>; |
| 3755 | + auto singer_info = SingerInfoMessage(singer_proto); |
| 3756 | + auto update = client.ExecuteDml( |
| 3757 | + std::move(txn), |
| 3758 | + google::cloud::spanner::SqlStatement( |
| 3759 | + "UPDATE Singers" |
| 3760 | + " SET SingerInfo = @singer_info," |
| 3761 | + " SingerInfoArray = @singer_info_array" |
| 3762 | + " WHERE SingerId = 1", |
| 3763 | + {{"singer_info", google::cloud::spanner::Value(singer_info)}, |
| 3764 | + {"singer_info_array", |
| 3765 | + google::cloud::spanner::Value( |
| 3766 | + std::vector<SingerInfoMessage>{singer_info})}})); |
| 3767 | + if (!update) return std::move(update).status(); |
| 3768 | + rows_modified = update->RowsModified(); |
| 3769 | + return google::cloud::spanner::Mutations{}; |
| 3770 | + }); |
| 3771 | + if (!commit_result) throw std::move(commit_result).status(); |
| 3772 | + std::cout << "Updated " << rows_modified << " row(s) " |
| 3773 | + << "[spanner_update_data_with_proto_message_column_with_dml]\n"; |
| 3774 | +} |
| 3775 | +// [END spanner_update_data_with_proto_message_column_with_dml] |
| 3776 | + |
| 3777 | +// [START spanner_query_with_proto_message_parameter] |
| 3778 | +void QueryWithProtoMessageParameter(google::cloud::spanner::Client client) { |
| 3779 | + google::cloud::spanner::SqlStatement select( |
| 3780 | + "SELECT SingerId, SingerInfo, SingerInfoArray FROM Singers" |
| 3781 | + " WHERE SingerInfo.Nationality = @nationality", |
| 3782 | + {{"nationality", google::cloud::spanner::Value("British")}}); |
| 3783 | + using SingerInfoMessage = google::cloud::spanner::ProtoMessage< |
| 3784 | + google::cloud::spanner::testing::SingerInfo>; |
| 3785 | + using RowType = std::tuple<std::int64_t, absl::optional<SingerInfoMessage>, |
| 3786 | + absl::optional<std::vector<SingerInfoMessage>>>; |
| 3787 | + auto rows = client.ExecuteQuery(std::move(select)); |
| 3788 | + for (auto& row : google::cloud::spanner::StreamOf<RowType>(rows)) { |
| 3789 | + if (!row) throw std::move(row).status(); |
| 3790 | + std::cout << "SingerId: " << std::get<0>(*row); |
| 3791 | + std::cout << ", SingerInfo: "; |
| 3792 | + auto singer_info = std::get<1>(*row); |
| 3793 | + if (!singer_info) { |
| 3794 | + std::cout << "NULL"; |
| 3795 | + } else { |
| 3796 | + std::cout << *singer_info; |
| 3797 | + } |
| 3798 | + std::cout << ", SingerInfoArray: "; |
| 3799 | + auto singer_info_array = std::get<2>(*row); |
| 3800 | + if (!singer_info_array) { |
| 3801 | + std::cout << "NULL"; |
| 3802 | + } else { |
| 3803 | + std::cout << "{"; |
| 3804 | + char const* sep = " "; |
| 3805 | + for (auto const& singer_info : *singer_info_array) { |
| 3806 | + std::cout << sep << singer_info; |
| 3807 | + sep = ", "; |
| 3808 | + } |
| 3809 | + std::cout << " }"; |
| 3810 | + } |
| 3811 | + std::cout << "\n"; |
| 3812 | + } |
| 3813 | + std::cout << "Query completed for " |
| 3814 | + << "[spanner_query_with_proto_message_parameter]\n"; |
| 3815 | +} |
| 3816 | +// [END spanner_query_with_proto_message_parameter] |
| 3817 | + |
| 3818 | +// [START spanner_update_data_with_proto_enum_column] |
| 3819 | +void UpdateDataWithProtoEnumColumn(google::cloud::spanner::Client client) { |
| 3820 | + using GenreEnum = |
| 3821 | + google::cloud::spanner::ProtoEnum<google::cloud::spanner::testing::Genre>; |
| 3822 | + auto singer_genre = GenreEnum(google::cloud::spanner::testing::Genre::FOLK); |
| 3823 | + auto commit_results = |
| 3824 | + client.CommitAtLeastOnce({google::cloud::spanner::Mutations{ |
| 3825 | + google::cloud::spanner::InsertOrUpdateMutationBuilder( |
| 3826 | + "Singers", {"SingerId", "SingerGenre", "SingerGenreArray"}) |
| 3827 | + .EmplaceRow(2, singer_genre, std::vector<GenreEnum>{singer_genre}) |
| 3828 | + .EmplaceRow(3, absl::optional<GenreEnum>(), |
| 3829 | + absl::optional<std::vector<GenreEnum>>()) |
| 3830 | + .Build()}}); |
| 3831 | + for (auto& commit_result : commit_results) { |
| 3832 | + if (!commit_result) throw std::move(commit_result).status(); |
| 3833 | + } |
| 3834 | + std::cout << "Update was successful " |
| 3835 | + << "[spanner_update_data_with_proto_enum_column]\n"; |
| 3836 | +} |
| 3837 | +// [END spanner_update_data_with_proto_enum_column] |
| 3838 | + |
| 3839 | +// [START spanner_update_data_with_proto_enum_column_with_dml] |
| 3840 | +void UpdateDataWithProtoEnumColumnWithDml( |
| 3841 | + google::cloud::spanner::Client client) { |
| 3842 | + std::int64_t rows_modified = 0; |
| 3843 | + auto commit_result = client.Commit( |
| 3844 | + [&client, &rows_modified](google::cloud::spanner::Transaction txn) |
| 3845 | + -> google::cloud::StatusOr<google::cloud::spanner::Mutations> { |
| 3846 | + using GenreEnum = google::cloud::spanner::ProtoEnum< |
| 3847 | + google::cloud::spanner::testing::Genre>; |
| 3848 | + auto singer_genre = |
| 3849 | + GenreEnum(google::cloud::spanner::testing::Genre::ROCK); |
| 3850 | + auto update = client.ExecuteDml( |
| 3851 | + std::move(txn), |
| 3852 | + google::cloud::spanner::SqlStatement( |
| 3853 | + "UPDATE Singers" |
| 3854 | + " SET SingerGenre = @singer_genre," |
| 3855 | + " SingerGenreArray = @singer_genre_array" |
| 3856 | + " WHERE SingerId = 1", |
| 3857 | + {{"singer_genre", google::cloud::spanner::Value(singer_genre)}, |
| 3858 | + {"singer_genre_array", |
| 3859 | + google::cloud::spanner::Value( |
| 3860 | + std::vector<GenreEnum>{singer_genre})}})); |
| 3861 | + if (!update) return std::move(update).status(); |
| 3862 | + rows_modified = update->RowsModified(); |
| 3863 | + return google::cloud::spanner::Mutations{}; |
| 3864 | + }); |
| 3865 | + if (!commit_result) throw std::move(commit_result).status(); |
| 3866 | + std::cout << "Updated " << rows_modified << " row(s) " |
| 3867 | + << "[spanner_update_data_with_proto_enum_column_with_dml]\n"; |
| 3868 | +} |
| 3869 | +// [END spanner_update_data_with_proto_enum_column_with_dml] |
| 3870 | + |
| 3871 | +// [START spanner_query_with_proto_enum_parameter] |
| 3872 | +void QueryWithProtoEnumParameter(google::cloud::spanner::Client client) { |
| 3873 | + using GenreEnum = |
| 3874 | + google::cloud::spanner::ProtoEnum<google::cloud::spanner::testing::Genre>; |
| 3875 | + auto singer_genre = GenreEnum(google::cloud::spanner::testing::Genre::ROCK); |
| 3876 | + google::cloud::spanner::SqlStatement select( |
| 3877 | + "SELECT SingerId, SingerGenre, SingerGenreArray FROM Singers" |
| 3878 | + " WHERE SingerGenre = @singer_genre", |
| 3879 | + {{"singer_genre", google::cloud::spanner::Value(singer_genre)}}); |
| 3880 | + using RowType = std::tuple<std::int64_t, absl::optional<GenreEnum>, |
| 3881 | + absl::optional<std::vector<GenreEnum>>>; |
| 3882 | + auto rows = client.ExecuteQuery(std::move(select)); |
| 3883 | + for (auto& row : google::cloud::spanner::StreamOf<RowType>(rows)) { |
| 3884 | + if (!row) throw std::move(row).status(); |
| 3885 | + std::cout << "SingerId: " << std::get<0>(*row); |
| 3886 | + std::cout << ", SingerGenre: "; |
| 3887 | + auto singer_genre = std::get<1>(*row); |
| 3888 | + if (!singer_genre) { |
| 3889 | + std::cout << "NULL"; |
| 3890 | + } else { |
| 3891 | + std::cout << *singer_genre; |
| 3892 | + } |
| 3893 | + std::cout << ", SingerGenreArray: "; |
| 3894 | + auto singer_genre_array = std::get<2>(*row); |
| 3895 | + if (!singer_genre_array) { |
| 3896 | + std::cout << "NULL"; |
| 3897 | + } else { |
| 3898 | + std::cout << "{"; |
| 3899 | + char const* sep = " "; |
| 3900 | + for (auto const& singer_genre : *singer_genre_array) { |
| 3901 | + std::cout << sep << singer_genre; |
| 3902 | + sep = ", "; |
| 3903 | + } |
| 3904 | + std::cout << " }"; |
| 3905 | + } |
| 3906 | + std::cout << "\n"; |
| 3907 | + } |
| 3908 | + std::cout << "Query completed for " |
| 3909 | + << "[spanner_query_with_proto_enum_parameter]\n"; |
| 3910 | +} |
| 3911 | +// [END spanner_query_with_proto_enum_parameter] |
| 3912 | + |
3652 | 3913 | void ExampleStatusOr(google::cloud::spanner::Client client) { |
3653 | 3914 | //! [example-status-or] |
3654 | 3915 | namespace spanner = ::google::cloud::spanner; |
@@ -4292,6 +4553,7 @@ int RunOneCommand(std::vector<std::string> argv) { |
4292 | 4553 | make_database_command_entry("list-database-roles", ListDatabaseRoles), |
4293 | 4554 | make_database_command_entry("add-column", AddColumn), |
4294 | 4555 | make_database_command_entry("add-timestamp-column", AddTimestampColumn), |
| 4556 | + make_database_command_entry("drop-column", DropColumn), |
4295 | 4557 | {"list-databases", ListDatabasesCommand}, |
4296 | 4558 | {"create-backup", CreateBackupCommand}, |
4297 | 4559 | {"restore-database", RestoreDatabaseCommand}, |
@@ -4411,6 +4673,21 @@ int RunOneCommand(std::vector<std::string> argv) { |
4411 | 4673 | make_command_entry("make-delete-mutation", MakeDeleteMutation), |
4412 | 4674 | make_command_entry("query-information-schema-database-options", |
4413 | 4675 | QueryInformationSchemaDatabaseOptions), |
| 4676 | + make_database_command_entry("spanner_add_proto_type_columns", |
| 4677 | + AddProtoTypeColumns), |
| 4678 | + make_command_entry("spanner_update_data_with_proto_message_column", |
| 4679 | + UpdateDataWithProtoMessageColumn), |
| 4680 | + make_command_entry( |
| 4681 | + "spanner_update_data_with_proto_message_column_with_dml", |
| 4682 | + UpdateDataWithProtoMessageColumnWithDml), |
| 4683 | + make_command_entry("spanner_query_with_proto_message_parameter", |
| 4684 | + QueryWithProtoMessageParameter), |
| 4685 | + make_command_entry("spanner_update_data_with_proto_enum_column", |
| 4686 | + UpdateDataWithProtoEnumColumn), |
| 4687 | + make_command_entry("spanner_update_data_with_proto_enum_column_with_dml", |
| 4688 | + UpdateDataWithProtoEnumColumnWithDml), |
| 4689 | + make_command_entry("spanner_query_with_proto_enum_parameter", |
| 4690 | + QueryWithProtoEnumParameter), |
4414 | 4691 | }; |
4415 | 4692 |
|
4416 | 4693 | static std::string usage_msg = [&argv, &commands] { |
@@ -5231,6 +5508,44 @@ void RunAll(bool emulator) { |
5231 | 5508 | SampleBanner("spanner_drop_database"); |
5232 | 5509 | DropDatabase(database_admin_client, project_id, instance_id, database_id); |
5233 | 5510 | } |
| 5511 | + |
| 5512 | + if (!emulator) { // proto columns and enums |
| 5513 | + SampleBanner("spanner_create_database"); |
| 5514 | + CreateDatabase(database_admin_client, project_id, instance_id, database_id); |
| 5515 | + |
| 5516 | + SampleBanner("drop-column"); |
| 5517 | + DropColumn(database_admin_client, project_id, instance_id, database_id); |
| 5518 | + |
| 5519 | + SampleBanner("spanner_add_proto_type_columns"); |
| 5520 | + AddProtoTypeColumns(database_admin_client, project_id, instance_id, |
| 5521 | + database_id); |
| 5522 | + |
| 5523 | + client = MakeSampleClient(project_id, instance_id, database_id); |
| 5524 | + |
| 5525 | + SampleBanner("insert-mutation-builder"); |
| 5526 | + InsertMutationBuilder(client); |
| 5527 | + |
| 5528 | + SampleBanner("spanner_update_data_with_proto_message_column"); |
| 5529 | + UpdateDataWithProtoMessageColumn(client); |
| 5530 | + |
| 5531 | + SampleBanner("spanner_update_data_with_proto_message_column_with_dml"); |
| 5532 | + UpdateDataWithProtoMessageColumnWithDml(client); |
| 5533 | + |
| 5534 | + SampleBanner("spanner_query_with_proto_message_parameter"); |
| 5535 | + QueryWithProtoMessageParameter(client); |
| 5536 | + |
| 5537 | + SampleBanner("spanner_update_data_with_proto_enum_column"); |
| 5538 | + UpdateDataWithProtoEnumColumn(client); |
| 5539 | + |
| 5540 | + SampleBanner("spanner_update_data_with_proto_enum_column_with_dml"); |
| 5541 | + UpdateDataWithProtoEnumColumnWithDml(client); |
| 5542 | + |
| 5543 | + SampleBanner("spanner_query_with_proto_enum_parameter"); |
| 5544 | + QueryWithProtoEnumParameter(client); |
| 5545 | + |
| 5546 | + SampleBanner("spanner_drop_database"); |
| 5547 | + DropDatabase(database_admin_client, project_id, instance_id, database_id); |
| 5548 | + } |
5234 | 5549 | } |
5235 | 5550 |
|
5236 | 5551 | bool AutoRun() { |
|
0 commit comments