diff --git a/.doc_gen/metadata/rds_metadata.yaml b/.doc_gen/metadata/rds_metadata.yaml index c52096a9f6c..6a7c2e3be93 100644 --- a/.doc_gen/metadata/rds_metadata.yaml +++ b/.doc_gen/metadata/rds_metadata.yaml @@ -126,6 +126,15 @@ rds_CreateDBInstance: - description: snippet_tags: - php.example_code.rds.createDBInstance.complete + Swift: + versions: + - sdk_version: 1 + github: swift/example_code/rds + excerpts: + - description: + snippet_tags: + - swift.rds.import + - swift.rds.CreateDBInstance services: rds: {CreateDBInstance} rds_DeleteDBInstance: @@ -194,6 +203,15 @@ rds_DeleteDBInstance: - description: snippet_tags: - php.example_code.rds.deleteDBInstance.complete + Swift: + versions: + - sdk_version: 1 + github: swift/example_code/rds + excerpts: + - description: + snippet_tags: + - swift.rds.import + - swift.rds.DeleteDBInstance services: rds: {DeleteDBInstance} rds_DescribeAccountAttributes: @@ -292,6 +310,15 @@ rds_DescribeDBInstances: - description: snippet_tags: - php.example_code.rds.describeDBInstances.complete + Swift: + versions: + - sdk_version: 1 + github: swift/example_code/rds + excerpts: + - description: + snippet_tags: + - swift.rds.import + - swift.rds.DescribeDBInstances services: rds: {DescribeDBInstances} rds_ModifyDBInstance: @@ -389,6 +416,15 @@ rds_DescribeDBParameterGroups: - cpp.example_code.rds.client - cpp.example_code.rds.DescribeDBParameterGroups1 - cpp.example_code.rds.DescribeDBParameterGroups2 + Swift: + versions: + - sdk_version: 1 + github: swift/example_code/rds + excerpts: + - description: + snippet_tags: + - swift.rds.import + - swift.rds.DescribeDBParameterGroups services: rds: {DescribeDBParameterGroups} rds_CreateDBParameterGroup: @@ -441,6 +477,15 @@ rds_CreateDBParameterGroup: - cpp.example_code.rds.client_configuration - cpp.example_code.rds.client - cpp.example_code.rds.CreateDBParameterGroup + Swift: + versions: + - sdk_version: 1 + github: swift/example_code/rds + excerpts: + - description: + snippet_tags: + - swift.rds.import + - swift.rds.CreateDBParameterGroup services: rds: {CreateDBParameterGroup} rds_DeleteDBParameterGroup: @@ -493,6 +538,15 @@ rds_DeleteDBParameterGroup: - cpp.example_code.rds.client_configuration - cpp.example_code.rds.client - cpp.example_code.rds.DeleteDBParameterGroup + Swift: + versions: + - sdk_version: 1 + github: swift/example_code/rds + excerpts: + - description: + snippet_tags: + - swift.rds.import + - swift.rds.DeleteDBParameterGroup services: rds: {DeleteDBParameterGroup} rds_DescribeDBParameters: @@ -554,6 +608,15 @@ rds_DescribeDBParameters: - cpp.example_code.rds.client_configuration - cpp.example_code.rds.client - cpp.example_code.rds.DescribeDBParameters + Swift: + versions: + - sdk_version: 1 + github: swift/example_code/rds + excerpts: + - description: + snippet_tags: + - swift.rds.import + - swift.rds.DescribeDBParameters services: rds: {DescribeDBParameters} rds_ModifyDBParameterGroup: @@ -606,6 +669,15 @@ rds_ModifyDBParameterGroup: - cpp.example_code.rds.client_configuration - cpp.example_code.rds.client - cpp.example_code.rds.ModifyDBParameterGroup + Swift: + versions: + - sdk_version: 1 + github: swift/example_code/rds + excerpts: + - description: + snippet_tags: + - swift.rds.import + - swift.rds.ModifyDBParameterGroup services: rds: {ModifyDBParameterGroup} rds_CreateDBSnapshot: @@ -675,6 +747,15 @@ rds_CreateDBSnapshot: - description: snippet_tags: - php.example_code.rds.createDBSnapshot.complete + Swift: + versions: + - sdk_version: 1 + github: swift/example_code/rds + excerpts: + - description: + snippet_tags: + - swift.rds.import + - swift.rds.CreateDBSnapshot services: rds: {CreateDBSnapshot} rds_DescribeDBSnapshots: @@ -727,6 +808,15 @@ rds_DescribeDBSnapshots: - cpp.example_code.rds.client_configuration - cpp.example_code.rds.client - cpp.example_code.rds.DescribeDBSnapshots + Swift: + versions: + - sdk_version: 1 + github: swift/example_code/rds + excerpts: + - description: + snippet_tags: + - swift.rds.import + - swift.rds.DescribeDBSnapshots services: rds: {DescribeDBSnapshots} rds_DescribeDBEngineVersions: @@ -779,6 +869,15 @@ rds_DescribeDBEngineVersions: - cpp.example_code.rds.client_configuration - cpp.example_code.rds.client - cpp.example_code.rds.DescribeDBEngineVersions + Swift: + versions: + - sdk_version: 1 + github: swift/example_code/rds + excerpts: + - description: + snippet_tags: + - swift.rds.import + - swift.rds.DescribeDBEngineVersions services: rds: {DescribeDBEngineVersions} rds_DescribeOrderableDBInstanceOptions: @@ -822,6 +921,15 @@ rds_DescribeOrderableDBInstanceOptions: - cpp.example_code.rds.client_configuration - cpp.example_code.rds.client - cpp.example_code.rds.DescribeOrderableDBInstanceOptions + Swift: + versions: + - sdk_version: 1 + github: swift/example_code/rds + excerpts: + - description: + snippet_tags: + - swift.rds.import + - swift.rds.DescribeOrderableDBInstanceOptions services: rds: {DescribeOrderableDBInstanceOptions} rds_GenerateRDSAuthToken: @@ -916,6 +1024,17 @@ rds_Scenario_GetStartedInstances: snippet_tags: - cpp.example_code.rds.client_configuration - cpp.example_code.rds.get_started_instances + Swift: + versions: + - sdk_version: 1 + github: swift/example_code/rds + excerpts: + - description: The Package.swift file. + snippet_tags: + - swift.rds.scenario.package + - description: The Swift code file, entry.swift. + snippet_tags: + - swift.rds.scenario services: rds: {CreateDBInstance, CreateDBParameterGroup, CreateDBSnapshot, DeleteDBInstance, DeleteDBParameterGroup, DescribeDBInstances, DescribeDBEngineVersions, DescribeDBParameterGroups, DescribeDBParameters, DescribeDBSnapshots, DescribeOrderableDBInstanceOptions, diff --git a/swift/example_code/rds/README.md b/swift/example_code/rds/README.md new file mode 100644 index 00000000000..f324bcc0462 --- /dev/null +++ b/swift/example_code/rds/README.md @@ -0,0 +1,123 @@ +# Amazon RDS code examples for the SDK for Swift + +## Overview + +Shows how to use the AWS SDK for Swift to work with Amazon Relational Database Service (Amazon RDS). + + + + +_Amazon RDS is a web service that makes it easier to set up, operate, and scale a relational database in the cloud._ + +## ⚠ Important + +* Running this code might result in charges to your AWS account. For more details, see [AWS Pricing](https://aws.amazon.com/pricing/) and [Free Tier](https://aws.amazon.com/free/). +* Running the tests might result in charges to your AWS account. +* We recommend that you grant your code least privilege. At most, grant only the minimum permissions required to perform the task. For more information, see [Grant least privilege](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege). +* This code is not tested in every AWS Region. For more information, see [AWS Regional Services](https://aws.amazon.com/about-aws/global-infrastructure/regional-product-services). + + + + +## Code examples + +### Prerequisites + +For prerequisites, see the [README](../../README.md#Prerequisites) in the `swift` folder. + + + + + +### Basics + +Code examples that show you how to perform the essential operations within a service. + +- [Learn the basics](scenario/Package.swift) + + +### Single actions + +Code excerpts that show you how to call individual service functions. + +- [CreateDBInstance](scenario/Sources/entry.swift#L529) +- [CreateDBParameterGroup](scenario/Sources/entry.swift#L326) +- [CreateDBSnapshot](scenario/Sources/entry.swift#L627) +- [DeleteDBInstance](scenario/Sources/entry.swift#L705) +- [DeleteDBParameterGroup](scenario/Sources/entry.swift#L770) +- [DescribeDBEngineVersions](scenario/Sources/entry.swift#L303) +- [DescribeDBInstances](scenario/Sources/entry.swift#L581) +- [DescribeDBParameterGroups](scenario/Sources/entry.swift#L350) +- [DescribeDBParameters](scenario/Sources/entry.swift#L374) +- [DescribeDBSnapshots](scenario/Sources/entry.swift#L656) +- [DescribeOrderableDBInstanceOptions](scenario/Sources/entry.swift#L478) +- [ModifyDBParameterGroup](scenario/Sources/entry.swift#L413) + + + + + +## Run the examples + +### Instructions + +To build any of these examples from a terminal window, navigate into its +directory, then use the following command: + +``` +$ swift build +``` + +To build one of these examples in Xcode, navigate to the example's directory +(such as the `ListUsers` directory, to build that example). Then type `xed.` +to open the example directory in Xcode. You can then use standard Xcode build +and run commands. + + + + + +#### Learn the basics + +This example shows you how to do the following: + +- Create a custom DB parameter group and set parameter values. +- Create a DB instance that's configured to use the parameter group. The DB instance also contains a database. +- Take a snapshot of the instance. +- Delete the instance and parameter group. + + + + + + + + + +### Tests + +⚠ Running tests might result in charges to your AWS account. + + +To find instructions for running these tests, see the [README](../../README.md#Tests) +in the `swift` folder. + + + + + + +## Additional resources + +- [Amazon RDS User Guide](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Welcome.html) +- [Amazon RDS API Reference](https://docs.aws.amazon.com/AmazonRDS/latest/APIReference/Welcome.html) +- [SDK for Swift Amazon RDS reference](https://sdk.amazonaws.com/swift/api/awsrds/latest/documentation/awsrds) + + + + +--- + +Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 diff --git a/swift/example_code/rds/scenario/Package.swift b/swift/example_code/rds/scenario/Package.swift new file mode 100644 index 00000000000..63b70f5494e --- /dev/null +++ b/swift/example_code/rds/scenario/Package.swift @@ -0,0 +1,47 @@ +// swift-tools-version: 5.9 +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +// +// (swift-tools-version has two lines here because it needs to be the first +// line in the file, but it should also appear in the snippet below) +// +// snippet-start:[swift.rds.scenario.package] +// swift-tools-version: 5.9 +// +// The swift-tools-version declares the minimum version of Swift required to +// build this package. + +import PackageDescription + +let package = Package( + name: "rds-scenario", + // Let Xcode know the minimum Apple platforms supported. + platforms: [ + .macOS(.v13), + .iOS(.v15) + ], + dependencies: [ + // Dependencies declare other packages that this package depends on. + .package( + url: "https://github.com/awslabs/aws-sdk-swift", + from: "1.4.0"), + .package( + url: "https://github.com/apple/swift-argument-parser.git", + branch: "main" + ) + ], + targets: [ + // Targets are the basic building blocks of a package, defining a module or a test suite. + // Targets can depend on other targets in this package and products + // from dependencies. + .executableTarget( + name: "rds-scenario", + dependencies: [ + .product(name: "AWSRDS", package: "aws-sdk-swift"), + .product(name: "ArgumentParser", package: "swift-argument-parser") + ], + path: "Sources") + + ] +) +// snippet-end:[swift.rds.scenario.package] diff --git a/swift/example_code/rds/scenario/Sources/entry.swift b/swift/example_code/rds/scenario/Sources/entry.swift new file mode 100644 index 00000000000..b1cb2f90905 --- /dev/null +++ b/swift/example_code/rds/scenario/Sources/entry.swift @@ -0,0 +1,832 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +// +// snippet-start:[swift.rds.scenario] +// An example that shows how to use the AWS SDK for Swift to perform a variety +// of operations using Amazon Relational Database Service (RDS). +// + +import ArgumentParser +import Foundation +// snippet-start:[swift.rds.import] +import AWSRDS +// snippet-end:[swift.rds.import] + +struct ExampleCommand: ParsableCommand { + @Option(help: "The AWS Region to run AWS API calls in.") + var awsRegion = "us-east-1" + @Option(help: "The username to use for the database administrator.") + var dbUsername = "admin" + @Option(help: "The password to use for the database administrator.") + var dbPassword: String + + static var configuration = CommandConfiguration( + commandName: "rds-scenario", + abstract: """ + Performs various operations to demonstrate the use of Amazon RDS Instances + using the AWS SDK for Swift. + """, + discussion: """ + """ + ) + + /// Called by ``main()`` to run the bulk of the example. + func runAsync() async throws { + let example = try await Example(region: awsRegion, username: dbUsername, password: dbPassword) + + await example.run() + } +} + +class Example { + let rdsClient: RDSClient + + // Storage for AWS RDS properties + + let dbUsername: String + let dbPassword: String + var dbInstanceIdentifier: String + var dbSnapshotIdentifier: String + var dbParameterGroupName: String + var dbParameterGroup: RDSClientTypes.DBParameterGroup? + var selectedEngineVersion: String? + + init(region: String, username: String, password: String) async throws{ + let rdsConfig = try await RDSClient.RDSClientConfiguration(region: region) + rdsClient = RDSClient(config: rdsConfig) + + dbUsername = username + dbPassword = password + dbParameterGroupName = "" + dbInstanceIdentifier = "" + dbSnapshotIdentifier = "" + } + + /// The example's main body. + func run() async { + var parameterGroupFamilies: Set = [] + + //===================================================================== + // 1. Get available database engine families for MySQL. + //===================================================================== + + let engineVersions = await getDBEngineVersions(engineName: "mysql") + + for version in engineVersions { + if version.dbParameterGroupFamily != nil { + parameterGroupFamilies.insert(version.dbParameterGroupFamily!) + } + } + + if engineVersions.count > 0 { + selectedEngineVersion = engineVersions.last!.engineVersion + } else { + print("*** Unable to find a valid database engine version. Canceling operations.") + await cleanUp() + return + } + + print("Found \(parameterGroupFamilies.count) parameter group families:") + for family in parameterGroupFamilies { + print(" \(family)") + } + + //===================================================================== + // 2. Select an engine family and create a custom DB parameter group. + // We select a family by sorting the set of family names, then + // choosing the last one. + //===================================================================== + + let sortedFamilies = parameterGroupFamilies.sorted() + + guard let selectedFamily = sortedFamilies.last else { + print("*** Unable to find a database engine family. Canceling operations.") + await cleanUp() + return + } + + print("Selected database engine family \(selectedFamily)") + + dbParameterGroupName = tempName(prefix: "rds-example") + print("Creating a database parameter group named \(dbParameterGroupName) using \(selectedFamily)") + dbParameterGroup = await createDBParameterGroup(groupName: dbParameterGroupName, + familyName: selectedFamily) + + //===================================================================== + // 3. Get the parameter group's details. + //===================================================================== + + print("Getting the database parameter group list...") + let dbParameterGroupList = await describeDBParameterGroups(groupName: dbParameterGroupName) + guard let dbParameterGroupList else { + await cleanUp() + return + } + + print("Found \(dbParameterGroupList.count) parameter groups...") + for group in dbParameterGroupList { + print(" \(group.dbParameterGroupName ?? "")") + } + print() + + //===================================================================== + // 4. Get a list of the parameter group's parameters. This list is + // likely to be long, so use pagination. Find the + // auto_increment_offset and auto_increment_increment parameters. + //===================================================================== + + let parameters = await describeDBParameters(groupName: dbParameterGroupName) + + //===================================================================== + // 5. Parse and display each parameter's name, description, and + // allowed values. + //===================================================================== + + for parameter in parameters { + let name = parameter.parameterName + guard let name else { + print("*** Unable to get parameter name!") + continue + } + + if name == "auto_increment_offset" || name == "auto_increment_increment" { + print("Parameter \(name):") + print(" Value: \(parameter.parameterValue ?? "")") + print(" Data type: \(parameter.dataType ?? "")") + print(" Description: \(parameter.description ?? "")") + print(" Allowed values: \(parameter.allowedValues ?? "")") + print(" Data type: \(parameter.dataType ?? "")") + print(" Description: \(parameter.description ?? "")") + print(" Allowed values: \(parameter.allowedValues ?? " [RDSClientTypes.DBEngineVersion] { + do { + let output = try await rdsClient.describeDBEngineVersions( + input: DescribeDBEngineVersionsInput( + engine: engineName + ) + ) + + return output.dbEngineVersions ?? [] + } catch { + return [] + } + } + // snippet-end:[swift.rds.DescribeDBEngineVersions] + + // snippet-start:[swift.rds.CreateDBParameterGroup] + /// Create a new database parameter group with the specified name. + /// + /// - Parameters: + /// - groupName: The name of the new parameter group. + /// - familyName: The name of the parameter group family. + /// - Returns: + func createDBParameterGroup(groupName: String, familyName: String) async -> RDSClientTypes.DBParameterGroup? { + do { + let output = try await rdsClient.createDBParameterGroup( + input: CreateDBParameterGroupInput( + dbParameterGroupFamily: familyName, + dbParameterGroupName: groupName, + description: "Created using the AWS SDK for Swift" + ) + ) + return output.dbParameterGroup + } catch { + print("*** Error creating the parameter group: \(error.localizedDescription)") + return nil + } + } + // snippet-end:[swift.rds.CreateDBParameterGroup] + + // snippet-start:[swift.rds.DescribeDBParameterGroups] + /// Get descriptions of the database parameter groups matching the given + /// name. + /// + /// - Parameter groupName: The name of the parameter group to describe. + /// + /// - Returns: An array of [RDSClientTypes.DBParameterGroup] objects + /// describing the parameter group. + func describeDBParameterGroups(groupName: String) async -> [RDSClientTypes.DBParameterGroup]? { + do { + let output = try await rdsClient.describeDBParameterGroups( + input: DescribeDBParameterGroupsInput( + dbParameterGroupName: groupName + ) + ) + return output.dbParameterGroups + } catch { + print("*** Error getting the database parameter group's details: \(error.localizedDescription)") + return nil + } + } + // snippet-end:[swift.rds.DescribeDBParameterGroups] + + // snippet-start:[swift.rds.DescribeDBParametersPaginated] + // snippet-start:[swift.rds.DescribeDBParameters] + /// Returns the detailed parameter list for the specified database + /// parameter group. + /// + /// - Parameters: + /// - groupName: The name of the parameter group to return parameters for. + /// - source: The types of parameters to return (`user`, `system`, or + /// `engine-default`). + /// + /// - Returns: An array of `RdSClientTypes.Parameter` objects, each + /// describing one of the group's parameters. + func describeDBParameters(groupName: String, source: String? = nil) async -> [RDSClientTypes.Parameter] { + var parameterList: [RDSClientTypes.Parameter] = [] + + do { + let pages = rdsClient.describeDBParametersPaginated( + input: DescribeDBParametersInput( + dbParameterGroupName: groupName, + source: source + ) + ) + + for try await page in pages { + guard let parameters = page.parameters else { + return [] + } + + parameterList += parameters + } + } catch { + print("*** Error getting database parameters: \(error.localizedDescription)") + return [] + } + + return parameterList + } + // snippet-end:[swift.rds.DescribeDBParameters] + // snippet-end:[swift.rds.DescribeDBParametersPaginated] + + // snippet-start:[swift.rds.ModifyDBParameterGroup] + /// Demonstrates modifying two of the specified database parameter group's + /// parameters. + /// + /// - Parameter groupName: The name of the parameter group to change + /// parameters for. + func modifyDBParameters(groupName: String) async { + let parameter1 = RDSClientTypes.Parameter( + applyMethod: RDSClientTypes.ApplyMethod.immediate, + parameterName: "auto_increment_offset", + parameterValue: "5" + ) + let parameter2 = RDSClientTypes.Parameter( + applyMethod: RDSClientTypes.ApplyMethod.immediate, + parameterName: "auto_increment_increment", + parameterValue: "5" + ) + + let parameterList = [parameter1, parameter2] + + do { + _ = try await rdsClient.modifyDBParameterGroup( + input: ModifyDBParameterGroupInput( + dbParameterGroupName: groupName, + parameters: parameterList + ) + ) + + print("Successfully modified the parameter group \(groupName).") + } catch { + print("*** Error modifying the parameter group \(groupName): \(error.localizedDescription)") + } + } + // snippet-end:[swift.rds.ModifyDBParameterGroup] + + /// Output a list of the database engine versions supported by the + /// specified family. + /// + /// - Parameter family: The family for which to list allowed database + /// engines. + func listAllowedEngines(family: String?) async { + do { + let output = try await rdsClient.describeDBEngineVersions( + input: DescribeDBEngineVersionsInput( + dbParameterGroupFamily: family, + engine: "mysql" + ) + ) + + guard let engineVersions = output.dbEngineVersions else { + print("No engine versions returned.") + return + } + + print("Found \(engineVersions.count) database engine versions:") + for version in engineVersions { + print(" \(version.engineVersion ?? ""): \(version.dbEngineDescription ?? "")") + } + } catch { + print("*** Error getting database engine version list: \(error.localizedDescription)") + return + } + } + + // snippet-start:[swift.rds.DescribeOrderableDBInstanceOptionsPaginated] + // snippet-start:[swift.rds.DescribeOrderableDBInstanceOptions] + /// Print a list of available database instances with "micro" in the class + /// name, then return one of them to be used by other code. + /// + /// - Parameters: + /// - engine: The database engine for which to list database instance + /// classes. + /// - engineVersion: The database version for which to list instances. + /// + /// - Returns: An `RDSClientTypes.OrderableDBInstanceOption` describing + /// the selected instance type. + func chooseMicroInstance(engine: String = "mysql", engineVersion: String? = nil) async -> RDSClientTypes.OrderableDBInstanceOption? { + do { + let pages = rdsClient.describeOrderableDBInstanceOptionsPaginated( + input: DescribeOrderableDBInstanceOptionsInput( + engine: engine, + engineVersion: engineVersion + ) + ) + + var optionsList: [RDSClientTypes.OrderableDBInstanceOption] = [] + + for try await page in pages { + guard let orderableDBInstanceOptions = page.orderableDBInstanceOptions else { + continue + } + + for dbInstanceOption in orderableDBInstanceOptions { + guard let className = dbInstanceOption.dbInstanceClass else { + continue + } + if className.contains("micro") { + optionsList.append(dbInstanceOption) + } + } + } + + print("Found \(optionsList.count) database instances of 'micro' class types:") + for dbInstanceOption in optionsList { + print(" \(dbInstanceOption.engine ?? "") \(dbInstanceOption.engineVersion ?? "") (\(dbInstanceOption.dbInstanceClass ?? ""))") + } + + return optionsList[0] + } catch { + print("*** Error getting a list of orderable instance options: \(error.localizedDescription)") + return nil + } + } + // snippet-end:[swift.rds.DescribeOrderableDBInstanceOptions] + // snippet-end:[swift.rds.DescribeOrderableDBInstanceOptionsPaginated] + + // snippet-start:[swift.rds.CreateDBInstance] + /// Create a new database instance. + /// + /// - Parameters: + /// - name: The name of the database to create. + /// - instanceIdentifier: The identifier to give the new database + /// instance. + /// - parameterGroupName: The name of the parameter group to associate + /// with the new database instance. + /// - engine: The database engine to use. + /// - engineVersion: The version of the database given by `engine` to + /// use. + /// - instanceClass: The memory and compute capacity of the database + /// instance, such as `db.m5.large``. + /// - username: The admin user's username to establish for the new + /// instance. + /// - password: The password to use for the specified user's access. + /// + /// - Returns: A string indicating the ARN of the newly created database + /// instance, or nil if the instance couldn't be created. + func createDBInstance(name: String, instanceIdentifier: String, parameterGroupName: String, + engine: String, engineVersion: String, instanceClass: String, + username: String, password: String) async -> String? { + do { + let output = try await rdsClient.createDBInstance( + input: CreateDBInstanceInput( + allocatedStorage: 100, + dbInstanceClass: instanceClass, + dbInstanceIdentifier: instanceIdentifier, + dbName: name, + dbParameterGroupName: parameterGroupName, + engine: engine, + engineVersion: engineVersion, + masterUserPassword: password, + masterUsername: username, + storageType: "gp2" + ) + ) + + guard let dbInstance = output.dbInstance else { + print("*** Unable to get the database instance.") + return nil + } + + return dbInstance.dbInstanceArn + } catch { + print("*** An error occurred while creating the database instance: \(error.localizedDescription)") + return nil + } + } + // snippet-end:[swift.rds.CreateDBInstance] + + // snippet-start:[swift.rds.DescribeDBInstances] + /// Wait until the specified database is available to use. + /// + /// - Parameter instanceIdentifier: The database instance identifier of the + /// database to wait for. + func waitUntilDBInstanceReady(instanceIdentifier: String) async -> RDSClientTypes.Endpoint? { + do { + putString("Waiting for the database instance to be ready to use. This may take 10 minutes or more...") + while true { + let output = try await rdsClient.describeDBInstances( + input: DescribeDBInstancesInput( + dbInstanceIdentifier: instanceIdentifier + ) + ) + + guard let instanceList = output.dbInstances else { + continue + } + + for instance in instanceList { + let status = instance.dbInstanceStatus + + guard let status else { + print("\nUnable to determine the status.") + continue + } + + if status.contains("available") { + return instance.endpoint + } else { + putString(".") + do { + try await Task.sleep(for: .seconds(15)) + } catch { + print("*** Error pausing the task!") + } + } + } + } + } catch { + print("*** Unable to wait until the database is ready: \(error.localizedDescription)") + return nil + } + } + // snippet-end:[swift.rds.DescribeDBInstances] + + // snippet-start:[swift.rds.CreateDBSnapshot] + /// Create a snapshot of the specified name. + /// + /// - Parameters: + /// - instanceIdentifier: The identifier of the database instance to + /// snapshot. + /// - snapshotIdentifier: A unique identifier to give the newly-created + /// snapshot. + func createDBSnapshot(instanceIdentifier: String, snapshotIdentifier: String) async { + do { + let output = try await rdsClient.createDBSnapshot( + input: CreateDBSnapshotInput( + dbInstanceIdentifier: instanceIdentifier, + dbSnapshotIdentifier: snapshotIdentifier + ) + ) + + guard let snapshot = output.dbSnapshot else { + print("No snapshot returned.") + return + } + + print("The snapshot has been created with ID \(snapshot.dbiResourceId ?? "")") + } catch { + print("*** Unable to create the database snapshot named \(snapshotIdentifier): \(error.localizedDescription)") + } + } + // snippet-end:[swift.rds.CreateDBSnapshot] + + // snippet-start:[swift.rds.DescribeDBSnapshots] + /// Wait until the specified database snapshot is available to use. + /// + /// - Parameters: + /// - instanceIdentifier: The identifier of the database for which the + /// snapshot was taken. + /// - snapshotIdentifier: The identifier of the snapshot to wait for. + func waitUntilDBSnapshotReady(instanceIdentifier: String, snapshotIdentifier: String) async { + var snapshotReady = false + + putString("Waiting for the snapshot to be ready...") + + do { + while !snapshotReady { + let output = try await rdsClient.describeDBSnapshots( + input: DescribeDBSnapshotsInput( + dbInstanceIdentifier: instanceIdentifier, + dbSnapshotIdentifier: snapshotIdentifier + ) + ) + + guard let snapshotList = output.dbSnapshots else { + return + } + + for snapshot in snapshotList { + guard let snapshotReadyStr = snapshot.status else { + return + } + + if snapshotReadyStr.contains("available") { + snapshotReady = true + print() + } else { + putString(".") + do { + try await Task.sleep(for: .seconds(15)) + } catch { + print("\n*** Error pausing the task!") + } + } + } + } + } catch { + print("\n*** Unable to wait for the database snapshot to be ready: \(error.localizedDescription)") + } + } + // snippet-end:[swift.rds.DescribeDBSnapshots] + + // snippet-start:[swift.rds.DeleteDBInstance] + /// Delete the specified database instance. + /// + /// - Parameter instanceIdentifier: The identifier of the database + /// instance to delete. + func deleteDBInstance(instanceIdentifier: String) async { + do { + _ = try await rdsClient.deleteDBInstance( + input: DeleteDBInstanceInput( + dbInstanceIdentifier: instanceIdentifier, + deleteAutomatedBackups: true, + skipFinalSnapshot: true + ) + ) + } catch { + print("*** Error deleting the database instance \(instanceIdentifier): \(error.localizedDescription)") + } + } + // snippet-end:[swift.rds.DeleteDBInstance] + + /// Wait until the specified database instance has been deleted. + /// + /// - Parameter instanceIdentifier: The identifier of the database + /// instance to wait for. + func waitUntilDBInstanceDeleted(instanceIdentifier: String) async { + putString("Waiting for the database instance to be deleted. This may take a few minutes...") + do { + var isDatabaseDeleted = false + var foundInstance = false + + while !isDatabaseDeleted { + let output = try await rdsClient.describeDBInstances(input: DescribeDBInstancesInput()) + guard let instanceList = output.dbInstances else { + return + } + + foundInstance = false + + for instance in instanceList { + guard let foundInstanceIdentifier = instance.dbInstanceIdentifier else { + continue + } + + if instanceIdentifier == foundInstanceIdentifier { + foundInstance = true + break + } else { + putString(".") + do { + try await Task.sleep(for: .seconds(15)) + } catch { + print("\n*** Error pausing the task!") + } + } + } + if !foundInstance { + isDatabaseDeleted = true + print() + } + } + } catch { + print("\n*** Error waiting for the database instance to be deleted: \(error.localizedDescription)") + } + } + + // snippet-start:[swift.rds.DeleteDBParameterGroup] + /// Delete the specified database parameter group. + /// + /// - Parameter groupName: The name of the parameter group to delete. + func deleteDBParameterGroup(groupName: String) async { + do { + _ = try await rdsClient.deleteDBParameterGroup( + input: DeleteDBParameterGroupInput( + dbParameterGroupName: groupName + ) + ) + } catch { + print("*** Error deleting the database parameter group \(groupName): \(error.localizedDescription)") + } + } + // snippet-end:[swift.rds.DeleteDBParameterGroup] + + /// Generate and return a unique file name that begins with the specified + /// string. + /// + /// - Parameters: + /// - prefix: Text to use at the beginning of the returned name. + /// + /// - Returns: A string containing a unique filename that begins with the + /// specified `prefix`. + /// + /// The returned name uses a random number between 1 million and 1 billion to + /// provide reasonable certainty of uniqueness for the purposes of this + /// example. + func tempName(prefix: String) -> String { + return "\(prefix)-\(Int.random(in: 1000000..<1000000000))" + } + + /// Print a string to standard output without a trailing newline, and + /// without buffering. + /// + /// - Parameter str: The string to output. + func putString(_ str: String = "") { + if str.length >= 1 { + let data = str.data(using: .utf8) + guard let data else { + return + } + FileHandle.standardOutput.write(data) + } + } +} + +/// The program's asynchronous entry point. +@main +struct Main { + static func main() async { + let args = Array(CommandLine.arguments.dropFirst()) + + do { + let command = try ExampleCommand.parse(args) + try await command.runAsync() + } catch { + ExampleCommand.exit(withError: error) + } + } +} +// snippet-end:[swift.rds.scenario] diff --git a/swift/example_code/swift-sdk/http-config/Package.swift b/swift/example_code/swift-sdk/http-config/Package.swift index 33d7e72d5ae..b0317651016 100644 --- a/swift/example_code/swift-sdk/http-config/Package.swift +++ b/swift/example_code/swift-sdk/http-config/Package.swift @@ -5,7 +5,6 @@ // (swift-tools-version has two lines here because it needs to be the first // line in the file, but it should also appear in the snippet below) // -// snippet-start:[swift.httpconfig.scenario.package] // swift-tools-version: 5.9 // // The swift-tools-version declares the minimum version of Swift required to @@ -44,4 +43,3 @@ let package = Package( ] ) -// snippet-end:[swift.httpconfig.scenario.package]