Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions src/scripting/alternator/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1149,6 +1149,8 @@ pub async fn query(
/// - `limit`: The maximum number of items to evaluate (optional).
/// - `validation`: An optional item count validation. Look at [extract_validation_args] for details.
/// - `with_result`: If true, the scan result is returned (default: false).
/// - `segment`: The segment to scan (optional).
/// - `total_segments`: The total number of segments (optional).
#[rune::function(instance)]
pub async fn scan(
ctx: Ref<Context>,
Expand All @@ -1171,9 +1173,33 @@ pub async fn scan(
LIMIT_KEY,
VALIDATION_KEY,
WITH_RESULT_KEY,
SEGMENT_KEY,
TOTAL_SEGMENTS_KEY,
],
)?;

if let Some(v) = params.get(SEGMENT_KEY) {
if let Ok(i) = v.as_signed() {
builder = builder.segment(match i32::try_from(i) {
Ok(val) => val,
Err(_) => return bad_input(format!("'{}' is out of range", SEGMENT_KEY)),
});
} else {
return bad_input(format!("'{}' must be an integer", SEGMENT_KEY));
}
}

if let Some(v) = params.get(TOTAL_SEGMENTS_KEY) {
if let Ok(i) = v.as_signed() {
builder = builder.total_segments(match i32::try_from(i) {
Ok(val) => val,
Err(_) => return bad_input(format!("'{}' is out of range", TOTAL_SEGMENTS_KEY)),
});
} else {
return bad_input(format!("'{}' must be an integer", TOTAL_SEGMENTS_KEY));
}
}

if let Some(v) = params.get(FILTER_EXPRESSION_KEY) {
if let Ok(s) = v.borrow_ref::<rune::alloc::String>() {
builder = builder.filter_expression(s.as_str().to_string());
Expand Down
2 changes: 2 additions & 0 deletions src/scripting/alternator/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ pub const PROJECTION_EXPRESSION_KEY: &str = "projection_expression";
pub const UPDATE_EXPRESSION_KEY: &str = "update";
pub const QUERY_EXPRESSION_KEY: &str = "query";
pub const FILTER_EXPRESSION_KEY: &str = "filter";
pub const SEGMENT_KEY: &str = "segment";
pub const TOTAL_SEGMENTS_KEY: &str = "total_segments";

fn alternator_set_to_rune<I, T, F>(key: &str, iter: I, wrapper: F) -> Result<Value, AlternatorError>
where
Expand Down
10 changes: 10 additions & 0 deletions workloads/alternator/api_demo.rn
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,16 @@ pub async fn run(db, i) {
}
}).await?;

// SCAN with segments
db.scan(TABLE, #{
filter: "age > :min_age",
"attribute_values": #{
":min_age": 18
},
"segment": 1,
"total_segments": 5
}).await?;

// DELETE Item
db.delete(TABLE, key, ()).await?;
}
18 changes: 18 additions & 0 deletions workloads/alternator/invalid_params.rn
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,24 @@ pub async fn run(db, i) {
filter: 123
}).await, "scan", "filter");

// Scan: segment must be integer and within range
assert_bad_param(db.scan(TABLE, #{
segment: "1"
}).await, "scan", "segment");

assert_bad_param(db.scan(TABLE, #{
segment: 1099511627776
}).await, "scan", "segment is out of range");

// Scan: total_segments must be integer and within range
assert_bad_param(db.scan(TABLE, #{
total_segments: "5"
}).await, "scan", "total_segments");

assert_bad_param(db.scan(TABLE, #{
total_segments: 1099511627776
}).await, "scan", "total_segments is out of range");

// Create Table: primary_key must be object or string
assert_bad_param(db.create_table("fail_table", #{
primary_key: 123
Expand Down
Loading