global secondary indexes
This commit is contained in:
94
dynamodb/key_codec_gsi.odin
Normal file
94
dynamodb/key_codec_gsi.odin
Normal file
@@ -0,0 +1,94 @@
|
||||
// key_codec_gsi.odin — Additional key codec functions for GSI support
|
||||
//
|
||||
// These procedures complement key_codec.odin with prefix builders needed
|
||||
// for GSI scanning and querying. They follow the same encoding conventions:
|
||||
// [entity_type][varint_len][segment_bytes]...
|
||||
//
|
||||
// Add the contents of this file to key_codec.odin (or keep as a separate file
|
||||
// in the dynamodb/ package).
|
||||
package dynamodb
|
||||
|
||||
import "core:bytes"
|
||||
|
||||
// Build GSI index prefix for scanning all entries in a GSI:
|
||||
// [gsi][table_name][index_name]
|
||||
build_gsi_prefix :: proc(table_name: string, index_name: string) -> []byte {
|
||||
buf: bytes.Buffer
|
||||
bytes.buffer_init_allocator(&buf, 0, 256, context.allocator)
|
||||
|
||||
bytes.buffer_write_byte(&buf, u8(Entity_Type.GSI))
|
||||
|
||||
encode_varint(&buf, len(table_name))
|
||||
bytes.buffer_write_string(&buf, table_name)
|
||||
|
||||
encode_varint(&buf, len(index_name))
|
||||
bytes.buffer_write_string(&buf, index_name)
|
||||
|
||||
return bytes.buffer_to_bytes(&buf)
|
||||
}
|
||||
|
||||
// Build GSI partition prefix for querying within a single partition:
|
||||
// [gsi][table_name][index_name][pk_value]
|
||||
build_gsi_partition_prefix :: proc(table_name: string, index_name: string, pk_value: []byte) -> []byte {
|
||||
buf: bytes.Buffer
|
||||
bytes.buffer_init_allocator(&buf, 0, 512, context.allocator)
|
||||
|
||||
bytes.buffer_write_byte(&buf, u8(Entity_Type.GSI))
|
||||
|
||||
encode_varint(&buf, len(table_name))
|
||||
bytes.buffer_write_string(&buf, table_name)
|
||||
|
||||
encode_varint(&buf, len(index_name))
|
||||
bytes.buffer_write_string(&buf, index_name)
|
||||
|
||||
encode_varint(&buf, len(pk_value))
|
||||
bytes.buffer_write(&buf, pk_value)
|
||||
|
||||
return bytes.buffer_to_bytes(&buf)
|
||||
}
|
||||
|
||||
// Decode a GSI key back into components
|
||||
Decoded_GSI_Key :: struct {
|
||||
table_name: string,
|
||||
index_name: string,
|
||||
pk_value: []byte,
|
||||
sk_value: Maybe([]byte),
|
||||
}
|
||||
|
||||
decode_gsi_key :: proc(key: []byte) -> (result: Decoded_GSI_Key, ok: bool) {
|
||||
decoder := Key_Decoder{data = key, pos = 0}
|
||||
|
||||
entity_type := decoder_read_entity_type(&decoder) or_return
|
||||
if entity_type != .GSI {
|
||||
return {}, false
|
||||
}
|
||||
|
||||
table_name_bytes := decoder_read_segment(&decoder) or_return
|
||||
result.table_name = string(table_name_bytes)
|
||||
|
||||
index_name_bytes := decoder_read_segment(&decoder) or_return
|
||||
result.index_name = string(index_name_bytes)
|
||||
|
||||
result.pk_value = decoder_read_segment(&decoder) or_return
|
||||
|
||||
if decoder_has_more(&decoder) {
|
||||
sk := decoder_read_segment(&decoder) or_return
|
||||
result.sk_value = sk
|
||||
}
|
||||
|
||||
return result, true
|
||||
}
|
||||
|
||||
// Build GSI prefix for deleting all GSI entries for a table (used by delete_table)
|
||||
// [gsi][table_name]
|
||||
build_gsi_table_prefix :: proc(table_name: string) -> []byte {
|
||||
buf: bytes.Buffer
|
||||
bytes.buffer_init_allocator(&buf, 0, 256, context.allocator)
|
||||
|
||||
bytes.buffer_write_byte(&buf, u8(Entity_Type.GSI))
|
||||
|
||||
encode_varint(&buf, len(table_name))
|
||||
bytes.buffer_write_string(&buf, table_name)
|
||||
|
||||
return bytes.buffer_to_bytes(&buf)
|
||||
}
|
||||
Reference in New Issue
Block a user