fix all the gsi stuff
This commit is contained in:
48
main.odin
48
main.odin
@@ -1237,15 +1237,26 @@ handle_query :: proc(engine: ^dynamodb.Storage_Engine, request: ^HTTP_Request, r
|
|||||||
|
|
||||||
// ---- GSI query path ----
|
// ---- GSI query path ----
|
||||||
if idx_name, has_idx := index_name.?; has_idx {
|
if idx_name, has_idx := index_name.?; has_idx {
|
||||||
_, gsi_found := dynamodb.find_gsi(&metadata, idx_name)
|
gsi, gsi_found := dynamodb.find_gsi(&metadata, idx_name)
|
||||||
if !gsi_found {
|
if !gsi_found {
|
||||||
make_error_response(response, .ValidationException,
|
make_error_response(response, .ValidationException,
|
||||||
fmt.tprintf("The table does not have the specified index: %s", idx_name))
|
fmt.tprintf("The table does not have the specified index: %s", idx_name))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
esk_gsi, esk_gsi_ok := dynamodb.parse_exclusive_start_key_gsi(
|
||||||
|
request.body, table_name, &metadata, gsi,
|
||||||
|
)
|
||||||
|
if !esk_gsi_ok {
|
||||||
|
make_error_response(response, .ValidationException, "Invalid ExclusiveStartKey")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer {
|
||||||
|
if k, ok_gsi := esk_gsi.?; ok_gsi { delete(k) }
|
||||||
|
}
|
||||||
|
|
||||||
result, err := dynamodb.gsi_query(engine, table_name, idx_name,
|
result, err := dynamodb.gsi_query(engine, table_name, idx_name,
|
||||||
pk_owned, exclusive_start_key, limit, sk_condition)
|
pk_owned, esk_gsi, limit, sk_condition)
|
||||||
if err != .None {
|
if err != .None {
|
||||||
handle_storage_error(response, err)
|
handle_storage_error(response, err)
|
||||||
return
|
return
|
||||||
@@ -1284,7 +1295,7 @@ handle_query :: proc(engine: ^dynamodb.Storage_Engine, request: ^HTTP_Request, r
|
|||||||
}
|
}
|
||||||
|
|
||||||
write_items_response_with_pagination_ex(
|
write_items_response_with_pagination_ex(
|
||||||
response, final_items, result.last_evaluated_key, &metadata, scanned_count,
|
response, final_items, result.last_evaluated_key, &metadata, scanned_count, gsi,
|
||||||
)
|
)
|
||||||
|
|
||||||
if has_proj && len(projection) > 0 {
|
if has_proj && len(projection) > 0 {
|
||||||
@@ -1420,14 +1431,25 @@ handle_scan :: proc(engine: ^dynamodb.Storage_Engine, request: ^HTTP_Request, re
|
|||||||
|
|
||||||
// ---- GSI scan path ----
|
// ---- GSI scan path ----
|
||||||
if idx_name, has_idx := index_name.?; has_idx {
|
if idx_name, has_idx := index_name.?; has_idx {
|
||||||
_, gsi_found := dynamodb.find_gsi(&metadata, idx_name)
|
gsi, gsi_found := dynamodb.find_gsi(&metadata, idx_name)
|
||||||
if !gsi_found {
|
if !gsi_found {
|
||||||
make_error_response(response, .ValidationException,
|
make_error_response(response, .ValidationException,
|
||||||
fmt.tprintf("The table does not have the specified index: %s", idx_name))
|
fmt.tprintf("The table does not have the specified index: %s", idx_name))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
result, err := dynamodb.gsi_scan(engine, table_name, idx_name, exclusive_start_key, limit)
|
esk_gsi, esk_gsi_ok := dynamodb.parse_exclusive_start_key_gsi(
|
||||||
|
request.body, table_name, &metadata, gsi,
|
||||||
|
)
|
||||||
|
if !esk_gsi_ok {
|
||||||
|
make_error_response(response, .ValidationException, "Invalid ExclusiveStartKey")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer {
|
||||||
|
if k, ok_gsi := esk_gsi.?; ok_gsi { delete(k) }
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := dynamodb.gsi_scan(engine, table_name, idx_name, esk_gsi, limit)
|
||||||
if err != .None {
|
if err != .None {
|
||||||
handle_storage_error(response, err)
|
handle_storage_error(response, err)
|
||||||
return
|
return
|
||||||
@@ -1466,7 +1488,7 @@ handle_scan :: proc(engine: ^dynamodb.Storage_Engine, request: ^HTTP_Request, re
|
|||||||
}
|
}
|
||||||
|
|
||||||
write_items_response_with_pagination_ex(
|
write_items_response_with_pagination_ex(
|
||||||
response, final_items, result.last_evaluated_key, &metadata, scanned_count,
|
response, final_items, result.last_evaluated_key, &metadata, scanned_count, gsi,
|
||||||
)
|
)
|
||||||
|
|
||||||
if has_proj && len(projection) > 0 {
|
if has_proj && len(projection) > 0 {
|
||||||
@@ -1579,13 +1601,13 @@ write_items_response_with_pagination_ex :: proc(
|
|||||||
last_evaluated_key_binary: Maybe([]byte),
|
last_evaluated_key_binary: Maybe([]byte),
|
||||||
metadata: ^dynamodb.Table_Metadata,
|
metadata: ^dynamodb.Table_Metadata,
|
||||||
scanned_count: int,
|
scanned_count: int,
|
||||||
|
gsi: ^dynamodb.Global_Secondary_Index = nil, // ← NEW parameter
|
||||||
) {
|
) {
|
||||||
builder := strings.builder_make(context.allocator)
|
builder := strings.builder_make(context.allocator)
|
||||||
defer strings.builder_destroy(&builder)
|
defer strings.builder_destroy(&builder)
|
||||||
|
|
||||||
strings.write_string(&builder, `{"Items":[`)
|
strings.write_string(&builder, `{"Items":[`)
|
||||||
|
|
||||||
// Use serialize_item_to_builder directly an NOT serialize_item
|
|
||||||
for item, i in items {
|
for item, i in items {
|
||||||
if i > 0 do strings.write_string(&builder, ",")
|
if i > 0 do strings.write_string(&builder, ",")
|
||||||
dynamodb.serialize_item_to_builder(&builder, item)
|
dynamodb.serialize_item_to_builder(&builder, item)
|
||||||
@@ -1597,7 +1619,16 @@ write_items_response_with_pagination_ex :: proc(
|
|||||||
fmt.sbprintf(&builder, "%d", scanned_count)
|
fmt.sbprintf(&builder, "%d", scanned_count)
|
||||||
|
|
||||||
if binary_key, has_last := last_evaluated_key_binary.?; has_last {
|
if binary_key, has_last := last_evaluated_key_binary.?; has_last {
|
||||||
lek_json, lek_ok := dynamodb.serialize_last_evaluated_key(binary_key, metadata)
|
lek_json: string
|
||||||
|
lek_ok: bool
|
||||||
|
|
||||||
|
// Use GSI serializer if we have a GSI, otherwise use base table serializer
|
||||||
|
if gsi != nil {
|
||||||
|
lek_json, lek_ok = dynamodb.serialize_last_evaluated_key_gsi(binary_key, metadata, gsi)
|
||||||
|
} else {
|
||||||
|
lek_json, lek_ok = dynamodb.serialize_last_evaluated_key(binary_key, metadata)
|
||||||
|
}
|
||||||
|
|
||||||
if lek_ok {
|
if lek_ok {
|
||||||
strings.write_string(&builder, `,"LastEvaluatedKey":`)
|
strings.write_string(&builder, `,"LastEvaluatedKey":`)
|
||||||
strings.write_string(&builder, lek_json)
|
strings.write_string(&builder, lek_json)
|
||||||
@@ -1606,7 +1637,6 @@ write_items_response_with_pagination_ex :: proc(
|
|||||||
|
|
||||||
strings.write_string(&builder, "}")
|
strings.write_string(&builder, "}")
|
||||||
|
|
||||||
// We have to Clone the string before passing to response_set_body
|
|
||||||
resp_body := strings.clone(strings.to_string(builder))
|
resp_body := strings.clone(strings.to_string(builder))
|
||||||
response_set_body(response, transmute([]byte)resp_body)
|
response_set_body(response, transmute([]byte)resp_body)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user