func convArray()

in sources/oracle/data.go [215:341]


func convArray(spannerType ddl.Type, srcTypeName string, v string) (interface{}, error) {
	v = strings.TrimSpace(v)
	// Handle empty array. Note that we use an empty NullString array
	// for all Spanner array types since this will be converted to the
	// appropriate type by the Spanner client.
	if v == "" {
		return []spanner.NullString{}, nil
	}

	// The Spanner client for go does not accept []interface{} for arrays.
	// Instead it only accepts slices of a specific type eg: []string
	// Hence we have to do the following case analysis.
	switch spannerType.Name {
	case ddl.String:
		var a []string
		var r []spanner.NullString
		err := json.Unmarshal([]byte(v), &a)
		if err != nil {
			return []spanner.NullString{}, err
		}

		for _, s := range a {
			if s == "NULL" {
				r = append(r, spanner.NullString{Valid: false})
				continue
			}
			r = append(r, spanner.NullString{StringVal: s, Valid: true})
		}
		return r, nil
	case ddl.Numeric:
		var a []interface{}
		var r []spanner.NullNumeric
		err := json.Unmarshal([]byte(v), &a)
		if err != nil {
			return []spanner.NullNumeric{}, err
		}
		for _, s := range a {
			if s == "NULL" {
				r = append(r, spanner.NullNumeric{Valid: false})
				continue
			}
			val := new(big.Rat)
			if _, ok := val.SetString(fmt.Sprint(s)); !ok {
				return []spanner.NullNumeric{}, fmt.Errorf("can't convert %q to big.Rat", s)
			}
			r = append(r, spanner.NullNumeric{Numeric: *val, Valid: true})
		}
		return r, nil
	case ddl.Int64:
		var a []interface{}
		var r []spanner.NullInt64
		err := json.Unmarshal([]byte(v), &a)
		if err != nil {
			return []spanner.NullInt64{}, err
		}
		for _, s := range a {
			if s == "NULL" {
				r = append(r, spanner.NullInt64{Valid: false})
				continue
			}
			val, err := convInt64(fmt.Sprint(s))
			if err != nil {
				return []spanner.NullInt64{}, err
			}
			r = append(r, spanner.NullInt64{Int64: val, Valid: true})
		}
		return r, nil
	case ddl.Float32:
		var a []interface{}
		var r []spanner.NullFloat32
		err := json.Unmarshal([]byte(v), &a)
		if err != nil {
			return []spanner.NullFloat32{}, err
		}
		for _, s := range a {
			if s == "NULL" {
				r = append(r, spanner.NullFloat32{Valid: false})
				continue
			}
			val, err := convFloat32(fmt.Sprint(s))
			if err != nil {
				return []spanner.NullFloat32{}, err
			}
			r = append(r, spanner.NullFloat32{Float32: val, Valid: true})
		}
		return r, nil
	case ddl.Float64:
		var a []interface{}
		var r []spanner.NullFloat64
		err := json.Unmarshal([]byte(v), &a)
		if err != nil {
			return []spanner.NullFloat64{}, err
		}
		for _, s := range a {
			if s == "NULL" {
				r = append(r, spanner.NullFloat64{Valid: false})
				continue
			}
			val, err := convFloat64(fmt.Sprint(s))
			if err != nil {
				return []spanner.NullFloat64{}, err
			}
			r = append(r, spanner.NullFloat64{Float64: val, Valid: true})
		}
		return r, nil
	case ddl.Date:
		var a []interface{}
		err := json.Unmarshal([]byte(v), &a)
		if err != nil {
			return []spanner.NullDate{}, err
		}
		var r []spanner.NullDate
		for _, s := range a {
			if s == "NULL" {
				r = append(r, spanner.NullDate{Valid: false})
				continue
			}
			val, err := convDate(fmt.Sprint(s))
			if err != nil {
				return []spanner.NullDate{}, err
			}
			r = append(r, spanner.NullDate{Date: val, Valid: true})
		}
		return r, nil
	}
	return []interface{}{}, fmt.Errorf("array type conversion not implemented for type %v", spannerType.Name)
}