in cassandra-bigtable-migration-tools/cassandra-bigtable-proxy/translator/utils.go [693:767]
func processListCollectionRaw(val, colFamily, cqlType string, prependCol []string, complexMeta map[string]*ComplexOperation) ([]Column, []interface{}, error) {
var newColumns []Column
var newValues []interface{}
var listDelete [][]byte
formattedStr := preprocessSetString(val)
var listValues []string
if err := json.Unmarshal([]byte(formattedStr), &listValues); err != nil {
return nil, nil, fmt.Errorf("error converting string to list<%s>: %w", cqlType, err)
}
prepend := false
if valExistInArr(prependCol, colFamily) {
prepend = true
}
for i, v := range listValues {
// Handle list index operation (e.g. "index:value") we are converting index op as this when reading updateElements
if strings.Contains(v, ":") {
splitV := strings.SplitN(v, ":", 2)
if len(splitV) != 2 {
return nil, nil, fmt.Errorf("invalid list index operation format in value: %s", v)
}
index := splitV[0]
v = splitV[1]
// Format the value according to the CQL type
formattedVal, err := formatValues(v, cqlType, primitive.ProtocolVersion4)
if err != nil {
return nil, nil, fmt.Errorf("error converting string to list<%s> value: %w", cqlType, err)
}
newComplexMeta := ComplexOperation{
UpdateListIndex: index,
Value: formattedVal,
}
complexMeta[colFamily] = &newComplexMeta
// Skip adding this value to newValues/newColumns as it's used for update metadata
continue
}
// Check if this value is marked for deletion in complex update for the list
if meta, ok := complexMeta[colFamily]; ok && meta.ListDelete {
formattedVal, err := formatValues(v, cqlType, primitive.ProtocolVersion4)
if err != nil {
return nil, nil, fmt.Errorf("error converting string to list<%s> value: %w", cqlType, err)
}
listDelete = append(listDelete, formattedVal)
continue
}
// Calculate encoded timestamp for the list element
encTime := getEncodedTimestamp(i, len(listValues), prepend)
// Create a new column identifier with the encoded timestamp as the name
c := Column{
Name: string(encTime),
ColumnFamily: colFamily,
CQLType: cqlType,
}
// Format the value
formattedVal, err := formatValues(v, cqlType, primitive.ProtocolVersion4)
if err != nil {
return nil, nil, fmt.Errorf("error converting string to list<%s> value: %w", cqlType, err)
}
newValues = append(newValues, formattedVal)
newColumns = append(newColumns, c)
}
if len(listDelete) > 0 {
if meta, ok := complexMeta[colFamily]; ok {
meta.ListDeleteValues = listDelete
} else {
complexMeta[colFamily] = &ComplexOperation{ListDeleteValues: listDelete}
}
}
return newColumns, newValues, nil
}