Skip to content

Commit f3b87e6

Browse files
shepazonEric Shepherd
andauthored
Swift basic scenario example for DynamoDB (#4403)
* Readme skeleton for Swift DynamoDB samples * WIP: Basic scenario for DDB on Swift * Readme skeleton for Swift DynamoDB samples * WIP: Basic scenario for DDB on Swift * Checkpoint * Final tweaks before PR * Readme update for DynamoDB * Fix incorrect SoS tags * Metadata for Swift DynamoDB scenario Add metadata for the DynamoDB scenario for Swift, and fix a couple of validation issues that have cropped up. * SoS metadata and tag fixes for Swift * Fix mis-paste of pathnames * More SoS cleanup * Add file left out of last commit * Typo fix * Update SDK metadata to fix validation error * Remove commented-out lines * Remove more commented out code * Text review feedback for DDB scenario for Swift * Update metadata and README for code review stage * Updated metadata for Swift DynamoDB --------- Co-authored-by: Eric Shepherd <[email protected]>
1 parent 740ae24 commit f3b87e6

File tree

8 files changed

+1310
-0
lines changed

8 files changed

+1310
-0
lines changed

.doc_gen/metadata/dynamodb_metadata.yaml

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,14 @@ dynamodb_CreateTable:
104104
- description:
105105
snippet_tags:
106106
- dynamodb.JavaScript.table.createTable
107+
Swift:
108+
versions:
109+
- sdk_version: 1
110+
github: swift/example_code/ddb
111+
excerpts:
112+
- description:
113+
snippet_tags:
114+
- ddb.swift.basics.createtable
107115
services:
108116
dynamodb: {CreateTable}
109117
dynamodb_BatchGetItem:
@@ -329,6 +337,14 @@ dynamodb_BatchWriteItem:
329337
- description:
330338
snippet_tags:
331339
- cpp.example_code.dynamodb.batch_write_item
340+
Swift:
341+
versions:
342+
- sdk_version: 1
343+
github: swift/example_code/ddb/
344+
excerpts:
345+
- description:
346+
snippet_tags:
347+
- ddb.swift.basics.populate
332348
services:
333349
dynamodb: {BatchWriteItem}
334350
dynamodb_DeleteTable:
@@ -434,6 +450,14 @@ dynamodb_DeleteTable:
434450
- description:
435451
snippet_tags:
436452
- dynamodb.JavaScript.table.deleteTable
453+
Swift:
454+
versions:
455+
- sdk_version: 1
456+
github: swift/example_code/ddb
457+
excerpts:
458+
- description:
459+
snippet_tags:
460+
- ddb.swift.basics.deletetable
437461
services:
438462
dynamodb: {DeleteTable}
439463
dynamodb_PutItem:
@@ -552,6 +576,15 @@ dynamodb_PutItem:
552576
- description: Put an item in a table using the &DDB; document client.
553577
snippet_tags:
554578
- dynamodb.JavaScript.docClient.put
579+
Swift:
580+
versions:
581+
- sdk_version: 1
582+
github: swift/example_code/ddb
583+
excerpts:
584+
- description:
585+
snippet_tags:
586+
- ddb.swift.basics.add-movie
587+
- ddb.swift.basics.movie.getasitem
555588
services:
556589
dynamodb: {PutItem}
557590
dynamodb_GetItem:
@@ -662,6 +695,14 @@ dynamodb_GetItem:
662695
- description: Get an item from a table using the &DDB; document client.
663696
snippet_tags:
664697
- dynamodb.JavaScript.docClient.get
698+
Swift:
699+
versions:
700+
- sdk_version: 1
701+
github: swift/example_code/ddb
702+
excerpts:
703+
- description:
704+
snippet_tags:
705+
- ddb.swift.basics.get
665706
services:
666707
dynamodb: {GetItem}
667708
dynamodb_UpdateItem:
@@ -772,6 +813,14 @@ dynamodb_UpdateItem:
772813
- description: Update items by batch in a table using PartiQL.
773814
snippet_tags:
774815
- dynamodb.JavaScript.partiQL.updateItemsV3
816+
Swift:
817+
versions:
818+
- sdk_version: 1
819+
github: swift/example_code/ddb
820+
excerpts:
821+
- description:
822+
snippet_tags:
823+
- ddb.swift.basics.update
775824
services:
776825
dynamodb: {UpdateItem}
777826
dynamodb_DeleteItem:
@@ -898,6 +947,14 @@ dynamodb_DeleteItem:
898947
- description:
899948
snippet_tags:
900949
- cpp.example_code.dynamodb.delete_item
950+
Swift:
951+
versions:
952+
- sdk_version: 1
953+
github: swift/example_code/ddb
954+
excerpts:
955+
- description:
956+
snippet_tags:
957+
- ddb.swift.basics.delete
901958
services:
902959
dynamodb: {DeleteItem}
903960
dynamodb_ListTables:
@@ -1128,6 +1185,14 @@ dynamodb_Query:
11281185
- description:
11291186
snippet_tags:
11301187
- dynamodb.JavaScript.docClient.query
1188+
Swift:
1189+
versions:
1190+
- sdk_version: 1
1191+
github: swift/example_code/ddb
1192+
excerpts:
1193+
- description:
1194+
snippet_tags:
1195+
- ddb.swift.basics.getMovies-year
11311196
services:
11321197
dynamodb: {Query}
11331198
dynamodb_Scan:
@@ -1237,6 +1302,14 @@ dynamodb_Scan:
12371302
- description:
12381303
snippet_tags:
12391304
- dynamodb.JavaScript.table.scan
1305+
Swift:
1306+
versions:
1307+
- sdk_version: 1
1308+
github: swift/example_code/ddb
1309+
excerpts:
1310+
- description:
1311+
snippet_tags:
1312+
- ddb.swift.basics.getmovies-range
12401313
services:
12411314
dynamodb: {Scan}
12421315
dynamodb_ExecuteStatement:
@@ -1701,6 +1774,23 @@ dynamodb_Scenario_GettingStartedMovies:
17011774
- cpp.example_code.dynamodb.scenario.createMoviesDynamoDBTable
17021775
- cpp.example_code.dynamodb.scenario.deleteMoviesDynamoDBTable
17031776
- cpp.example_code.dynamodb.scenario.waitTableActive
1777+
Swift:
1778+
versions:
1779+
- sdk_version: 1
1780+
github: swift/example_code/ddb
1781+
excerpts:
1782+
- description:
1783+
A Swift class that handles &DDB; calls to the &Swift;.
1784+
snippet_tags:
1785+
- ddb.swift.basics.movietable
1786+
- description: The structures used by the MovieTable class to
1787+
represent movies.
1788+
snippet_tags:
1789+
- ddb.swift.basics.movie
1790+
- description: A program that uses the MovieTable class to access
1791+
a &DDB; database.
1792+
snippet_tags:
1793+
- ddb.swift.basics
17041794
services:
17051795
dynamodb:
17061796
{

swift/example_code/ddb/README.md

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# DynamoDB code examples for the SDK for Swift
2+
## Overview
3+
This folder contains code examples demonstrating how to use the AWS SDK for
4+
Swift to use Amazon DynamoDB. This README discusses how to run these examples.
5+
6+
Amazon DynamoDB is a fully managed NoSQL database service that provides fast
7+
and predictable performance with seamless scalability. DynamoDB lets you
8+
offload the administrative burdens of operating and scaling a distributed
9+
database so that you don't have to worry about hardware provisioning, setup
10+
and configuration, replication, software patching, or cluster scaling.
11+
12+
## ⚠️ Important
13+
* Running this code might result in charges to your AWS account.
14+
* Running the tests might result in charges to your AWS account.
15+
* 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/DynamoDB/latest/UserGuide/best-practices.html#grant-least-privilege).
16+
* 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).
17+
18+
## Code examples
19+
20+
### Single actions
21+
Code excerpts that show you how to call individual service functions.
22+
* [Create a table](./basics/MovieList/MovieTable.swift)
23+
(`CreateTable`)
24+
* [Add an item to a table](./basics/MovieList/MovieTable.swift) (`PutItem`)
25+
* [Update an item](./basics/MovieList/MovieTable.swift) (`UpdateItem`)
26+
* [Add the contents of a JSON file to a table](./basics/MovieList/MovieTable.swift) (`BatchWriteItem`)
27+
* [Get an item by key](./basics/MovieList/MovieTable.swift) (`GetItem`)
28+
* [Delete an item by key](./basics/MovieList/MovieTable.swift) (`DeleteItem`)
29+
* [Query a table](./basics/MovieList/MovieTable.swift) (`Query`)
30+
* [Scan a table with pagination](./basics/MovieList/MovieTable.swift) (`Scan`)
31+
* [Delete a table](./basics/MovieList/MovieTable.swift) (`DeleteTable`)
32+
33+
### Scenarios
34+
Code examples that show you how to accomplish a specific task by calling multiple functions within the same service.
35+
36+
* [DynamoDB Basics](./basics/Sources/basics.swift). Demonstrates a common
37+
series of actions to create and perform common actions on a movie list
38+
database. (`Basics`)
39+
40+
<!-- ### Cross-service examples
41+
Sample applications that work across multiple AWS services.
42+
* [*Title of code example*](*relative link to code example*) --->
43+
44+
## Run the examples
45+
To build any of these examples from a terminal window, navigate into its
46+
directory, then use the following command:
47+
48+
```
49+
$ swift build
50+
```
51+
52+
To build one of these examples in Xcode, navigate to the example's directory
53+
(such as the `basics` directory, to build that example). Then type `xed.`
54+
to open the example directory in Xcode. You can then use standard Xcode build
55+
and run commands.
56+
57+
### Prerequisites
58+
See the [Prerequisites](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/swift#Prerequisites) section in the README for the AWS SDK for Swift examples repository.
59+
60+
## Tests
61+
⚠️ Running the tests might result in charges to your AWS account.
62+
63+
To run the tests for an example, use the command `swift test` in the example's directory.
64+
65+
## Additional resources
66+
* [DynamoDB Developer Guide](https://docs.aws.amazon.com/dynamodb/index.html)
67+
* [DynamoDB API Reference](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/)
68+
* [DynamoDB Developer Guide for Swift](https://docs.aws.amazon.com/sdk-for-swift/latest/developer-guide/examples-ddb.html)
69+
* [DynamoDB API Reference for Swift](https://awslabs.github.io/aws-sdk-swift/reference/0.x/AWSDynamoDB/Home)
70+
* [Security best practices for DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/best-practices-security.html)
71+
72+
_Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. SPDX-License-Identifier: Apache-2.0_
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
// snippet-start:[ddb.swift.basics.movie]
5+
import Foundation
6+
import AWSDynamoDB
7+
8+
// snippet-start:[ddb.swift.basics.details]
9+
/// The optional details about a movie.
10+
public struct Details: Codable {
11+
/// The movie's rating, if available.
12+
var rating: Double?
13+
/// The movie's plot, if available.
14+
var plot: String?
15+
}
16+
// snippet-end:[ddb.swift.basics.details]
17+
18+
/// A structure describing a movie. The `year` and `title` properties are
19+
/// required and are used as the key for Amazon DynamoDB operations. The
20+
/// `info` sub-structure's two properties, `rating` and `plot`, are optional.
21+
public struct Movie: Codable {
22+
/// The year in which the movie was released.
23+
var year: Int
24+
/// The movie's title.
25+
var title: String
26+
/// A `Details` object providing the optional movie rating and plot
27+
/// information.
28+
var info: Details
29+
30+
// snippet-start:[ddb.swift.basics.init]
31+
/// Create a `Movie` object representing a movie, given the movie's
32+
/// details.
33+
///
34+
/// - Parameters:
35+
/// - title: The movie's title (`String`).
36+
/// - year: The year in which the movie was released (`Int`).
37+
/// - rating: The movie's rating (optional `Double`).
38+
/// - plot: The movie's plot (optional `String`)
39+
init(title: String, year: Int, rating: Double? = nil, plot: String? = nil) {
40+
self.title = title
41+
self.year = year
42+
43+
self.info = Details(rating: rating, plot: plot)
44+
}
45+
// snippet-end:[ddb.swift.basics.init]
46+
47+
// snippet-start:[ddb.swift.basics.init-info]
48+
/// Create a `Movie` object representing a movie, given the movie's
49+
/// details.
50+
///
51+
/// - Parameters:
52+
/// - title: The movie's title (`String`).
53+
/// - year: The year in which the movie was released (`Int`).
54+
/// - info: The optional rating and plot information for the movie in a
55+
/// `Details` object.
56+
init(title: String, year: Int, info: Details?){
57+
self.title = title
58+
self.year = year
59+
60+
if info != nil {
61+
self.info = info!
62+
} else {
63+
self.info = Details(rating: nil, plot: nil)
64+
}
65+
}
66+
// snippet-end:[ddb.swift.basics.init-info]
67+
68+
// snippet-start:[ddb.swift.basics.init-withitem]
69+
///
70+
/// Return a new `MovieTable` object, given an array mapping string to Amazon
71+
/// DynamoDB attribute values.
72+
///
73+
/// - Parameter item: The item information provided to the form used by
74+
/// DynamoDB. This is an array of strings mapped to
75+
/// `DynamoDBClientTypes.AttributeValue` values.
76+
init(withItem item: [Swift.String:DynamoDBClientTypes.AttributeValue]) throws {
77+
// Read the attributes.
78+
79+
guard let titleAttr = item["title"],
80+
let yearAttr = item["year"] else {
81+
throw MoviesError.ItemNotFound
82+
}
83+
let infoAttr = item["info"] ?? nil
84+
85+
// Extract the values of the title and year attributes.
86+
87+
if case .s(let titleVal) = titleAttr {
88+
self.title = titleVal
89+
} else {
90+
throw MoviesError.InvalidAttributes
91+
}
92+
93+
if case .n(let yearVal) = yearAttr {
94+
self.year = Int(yearVal)!
95+
} else {
96+
throw MoviesError.InvalidAttributes
97+
}
98+
99+
// Extract the rating and/or plot from the `info` attribute, if
100+
// they're present.
101+
102+
var rating: Double? = nil
103+
var plot: String? = nil
104+
105+
if infoAttr != nil, case .m(let infoVal) = infoAttr {
106+
let ratingAttr = infoVal["rating"] ?? nil
107+
let plotAttr = infoVal["plot"] ?? nil
108+
109+
if ratingAttr != nil, case .n(let ratingVal) = ratingAttr {
110+
rating = Double(ratingVal) ?? nil
111+
}
112+
if plotAttr != nil, case .s(let plotVal) = plotAttr {
113+
plot = plotVal
114+
}
115+
}
116+
117+
self.info = Details(rating: rating, plot: plot)
118+
}
119+
// snippet-end:[ddb.swift.basics.init-withitem]
120+
121+
// snippet-start:[ddb.swift.basics.movie.getasitem]
122+
///
123+
/// Return an array mapping attribute names to Amazon DynamoDB attribute
124+
/// values, representing the contents of the `Movie` record as a DynamoDB
125+
/// item.
126+
///
127+
/// - Returns: The movie item as an array of type
128+
/// `[Swift.String:DynamoDBClientTypes.AttributeValue]`.
129+
///
130+
func getAsItem() async throws -> [Swift.String:DynamoDBClientTypes.AttributeValue] {
131+
// Build the item record, starting with the year and title, which are
132+
// always present.
133+
134+
var item: [Swift.String:DynamoDBClientTypes.AttributeValue] = [
135+
"year": .n(String(self.year)),
136+
"title": .s(self.title)
137+
]
138+
139+
// Add the `info` field with the rating and/or plot if they're
140+
// available.
141+
142+
var details: [Swift.String:DynamoDBClientTypes.AttributeValue] = [:]
143+
if (self.info.rating != nil || self.info.plot != nil) {
144+
if self.info.rating != nil {
145+
details["rating"] = .n(String(self.info.rating!))
146+
}
147+
if self.info.plot != nil {
148+
details["plot"] = .s(self.info.plot!)
149+
}
150+
}
151+
item["info"] = .m(details)
152+
153+
return item
154+
}
155+
// snippet-end:[ddb.swift.basics.movie.getasitem]
156+
}
157+
// snippet-end:[ddb.swift.basics.movie]

0 commit comments

Comments
 (0)