fn generate_query_expressions()

in src/data.rs [889:976]


fn generate_query_expressions(
    ts: &app::TableSchema,
    pval: &str,
    sort_key_expression: &Option<String>,
    index: &Option<String>,
) -> Result<GeneratedQueryParams, DyneinQueryParamsError> {
    let expression: String = String::from("#DYNEIN_PKNAME = :DYNEIN_PKVAL");
    let mut names = HashMap::<String, String>::new();
    let mut vals = HashMap::<String, AttributeValue>::new();
    let mut sort_key_of_target_table_or_index: Option<app::Key> = None;

    match index {
        None =>
        /* Query for base table */
        {
            debug!("Assigning PK name/value and sort key (if any)");
            names.insert(
                String::from("#DYNEIN_PKNAME"),
                String::from(&ts.clone().pk.name),
            );
            vals.insert(
                String::from(":DYNEIN_PKVAL"),
                build_attrval_scalar(&ts.pk.kind.to_string(), pval),
            );
            sort_key_of_target_table_or_index = ts.sk.clone();
        }
        Some(idx) =>
        /* Query for Secondary Index */
        {
            debug!("Specified Query target index name: {:?}", &idx);
            if let Some(table_indexes) = &ts.indexes {
                debug!("indexes attached to the table: {:?}", &table_indexes);
                for existing_idx in table_indexes {
                    // index name should be unique in a table. Even LSI and GSI don't have the same name.
                    if idx == &existing_idx.name {
                        names.insert(
                            String::from("#DYNEIN_PKNAME"),
                            String::from(&existing_idx.pk.name),
                        );
                        vals.insert(
                            String::from(":DYNEIN_PKVAL"),
                            build_attrval_scalar(&existing_idx.pk.kind.to_string(), pval),
                        );
                        sort_key_of_target_table_or_index = existing_idx.sk.clone();
                        break;
                    }
                }
            };

            // Exit with error if no effective secondary index found. Here "names" can be blank if:
            //   (1). no index is defined for the table, or
            //   (2). there're some index(es) but couldn't find specified name index
            if names.is_empty() {
                return Err(DyneinQueryParamsError::NoSuchIndex(
                    idx.to_string(),
                    ts.clone().name,
                ));
            }
        }
    }

    debug!(
        "Before appending sort key expression ... exp='{}', names='{:?}', vals={:?}",
        &expression, &names, &vals
    );
    match sort_key_expression {
        None =>
        /* No --sort-key option given. proceed with partition key condition only. */
        {
            Ok(GeneratedQueryParams {
                exp: Some(expression),
                names: if names.is_empty() { None } else { Some(names) },
                vals: Some(vals),
            })
        }
        Some(ske) =>
        /* As --sort-key option is given, parse it and append the built SK related condition to required PK expression. */
        {
            append_sort_key_expression(
                sort_key_of_target_table_or_index,
                &expression,
                ske,
                names,
                vals,
            )
        }
    }
}