in internal/databaseconnector/databaseconnector.go [293:361]
func parseIntoValues(resultRow string, dest ...any) error {
nullChar := "?" // Represents NULL characters in the query output.
matches := cmdResultPattern.FindAllStringSubmatch(resultRow, -1)
if len(matches) != len(dest) {
return fmt.Errorf("result has %d columns, but %d destination arguments provided", len(matches), len(dest))
}
// Parse each matched token as per the provided destination pointer type.
// For NULL values the value is set to the default/zero values.
for i, match := range matches {
if len(match) < 3 {
usagemetrics.Error(usagemetrics.HDBUserstoreKeyFailure)
return fmt.Errorf("could not parse result")
}
switch d := dest[i].(type) {
case (*string):
// Non primitive or alphanumeric data types are enclosed in quotes.
// For NULL values, match[2] is an empty string "".
if match[0] == nullChar || strings.HasPrefix(match[0], `"`) {
*d = match[2] // Gets result enclosed in quotes (e.g. strings, date, etc) as string.
continue
}
*d = match[0] // Gets result not enclosed in quotes (e.g. int, float, etc) as string.
case (*int64):
if match[0] == nullChar {
*d = 0
continue
}
val, err := strconv.ParseInt(match[0], 10, 64)
if err != nil {
return fmt.Errorf("failed to parse %s as int64: %v", match[0], err)
}
*d = val
case (*float64):
if match[0] == nullChar {
*d = 0.0
continue
}
val, err := strconv.ParseFloat(match[0], 64)
if err != nil {
return fmt.Errorf("failed to parse %s as float64: %v", match[0], err)
}
*d = val
case (*bool):
if match[0] == nullChar {
*d = false
continue
}
val, err := strconv.ParseBool(match[0])
if err != nil {
return fmt.Errorf("failed to parse %s as bool: %v", match[0], err)
}
*d = val
case (*any):
// Non primitive or alphanumeric data types are enclosed in quotes.
// For NULL values, match[2] is an empty string "".
if match[0] == nullChar || strings.HasPrefix(match[0], `"`) {
*d = match[2] // Gets result enclosed in quotes (e.g. strings, date, etc) as string.
continue
}
*d = match[0] // Gets result not enclosed in quotes (e.g. int, float, etc) as string.
default:
usagemetrics.Error(usagemetrics.HDBUserstoreKeyFailure)
return fmt.Errorf("unsupported destination argument type: %T", d)
}
}
return nil
}