///|
/// A small end-to-end example for DynamoDB Local at 127.0.0.1:8000.
async fn main {
let config : @lib.Config = {
endpoint: "http://127.0.0.1:8000",
region: "us-east-1",
credentials: {
access_key_id: "local",
secret_access_key: "local",
session_token: None,
},
}
let db = @lib.Client::new(config)
try db.create_table("MoonDynamoExample", "pk") |> ignore catch {
@lib.DynamoError::Service(_, "ResourceInUseException", _, _) => ()
error => raise error
}
try db.create_table("MoonDynamoExampleArchive", "pk") |> ignore catch {
@lib.DynamoError::Service(_, "ResourceInUseException", _, _) => ()
error => raise error
}
db.describe_table("MoonDynamoExample") |> ignore
let tables = db.list_tables(limit=1)
guard !tables.table_names.is_empty() else {
fail("ListTables returned no tables")
}
let all_tables = db.list_all_tables(limit=1)
let mut found_main = false
let mut found_archive = false
for name in all_tables {
if name == "MoonDynamoExample" {
found_main = true
}
if name == "MoonDynamoExampleArchive" {
found_archive = true
}
}
guard found_main && found_archive else {
fail("list_all_tables missed a page")
}
// "status" collides with a DynamoDB reserved word in expressions, so the
// query below reaches it through a #name placeholder.
let item : @lib.Item = Map([
("pk", @lib.Text("book#1")),
("title", @lib.Text("The MoonBit Book")),
("pages", @lib.Number("128")),
("status", @lib.Text("active")),
])
db.put_item("MoonDynamoExample", item)
let key : @lib.Item = Map([("pk", @lib.Text("book#1"))])
let found = db.get_item("MoonDynamoExample", key)
guard found is Some(found_item) else { fail("GetItem returned no item") }
guard found_item.get("title") == Some(@lib.Text("The MoonBit Book")) else {
fail("GetItem returned an unexpected item")
}
let selected = db.get_item(
"MoonDynamoExample",
key,
projection_expression="title, #st",
expression_attribute_names=Map([("#st", "status")]),
)
guard selected is Some(selected_item) else {
fail("projected GetItem returned no item")
}
guard selected_item.get("title") == Some(@lib.Text("The MoonBit Book")) &&
selected_item.get("status") == Some(@lib.Text("active")) &&
selected_item.get("pages") is None else {
fail("projected GetItem returned unexpected fields")
}
let batch = db.batch_get_item(
"MoonDynamoExample",
[key],
consistent_read=true,
projection_expression="pk, title, #st",
expression_attribute_names=Map([("#st", "status")]),
)
guard batch.items.length() == 1 &&
batch.unprocessed_keys.is_empty() &&
batch.items[0].get("pk") == Some(@lib.Text("book#1")) &&
batch.items[0].get("status") == Some(@lib.Text("active")) &&
batch.items[0].get("pages") is None else {
fail("projected BatchGetItem returned unexpected fields")
}
let updated = db.update_item(
"MoonDynamoExample",
key,
"SET pages = :pages",
expression_attribute_values=Map([
(":pages", @lib.Number("200")),
(":expected", @lib.Number("128")),
]),
condition_expression="pages = :expected",
return_values=AllNew,
)
guard updated is Some(book) && book.get("pages") == Some(@lib.Number("200")) else {
fail("UpdateItem did not apply the new page count")
}
try
db.update_item(
"MoonDynamoExample",
key,
"SET pages = :pages",
expression_attribute_values=Map([
(":pages", @lib.Number("999")),
(":expected", @lib.Number("128")),
]),
condition_expression="pages = :expected",
)
|> ignore
catch {
@lib.DynamoError::Service(400, "ConditionalCheckFailedException", _, _) =>
()
error => raise error
}
let after_rejected = db.get_item("MoonDynamoExample", key)
guard after_rejected is Some(book) &&
book.get("pages") == Some(@lib.Number("200")) else {
fail("failed conditional update changed the item")
}
let result = db.query(
"MoonDynamoExample",
"pk = :pk",
Map([(":pk", @lib.Text("book#1")), (":st", @lib.Text("active"))]),
filter_expression="#st = :st",
expression_attribute_names=Map([("#st", "status")]),
projection_expression="title",
)
guard result.items.length() == 1 &&
result.items[0].get("title") == Some(@lib.Text("The MoonBit Book")) &&
result.items[0].get("pages") is None else {
fail("Query projection returned unexpected fields")
}
let scanned = db.scan(
"MoonDynamoExample",
projection_expression="title, #st",
expression_attribute_names=Map([("#st", "status")]),
)
guard scanned.items.length() == 1 &&
scanned.items[0].get("status") == Some(@lib.Text("active")) &&
scanned.items[0].get("pages") is None else {
fail("Scan projection returned unexpected fields")
}
db.delete_item("MoonDynamoExample", key)
guard db.get_item("MoonDynamoExample", key) is None else {
fail("DeleteItem did not remove the item")
}
println("MoonDynamo local example passed")
}