func processListCollectionRaw()

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
}