예제 #1
0
// deconstructDatum converts a datum object to an arbitrary type
func deconstructDatum(datum *p.Datum, opts map[string]interface{}) (interface{}, error) {
	switch datum.GetType() {
	case p.Datum_R_NULL:
		return nil, nil
	case p.Datum_R_JSON:
		var v interface{}
		err := json.Unmarshal([]byte(datum.GetRStr()), &v)
		if err != nil {
			return nil, err
		}

		v, err = recursivelyConvertPseudotype(v, opts)
		if err != nil {
			return nil, err
		}

		return v, nil
	case p.Datum_R_BOOL:
		return datum.GetRBool(), nil
	case p.Datum_R_NUM:
		return datum.GetRNum(), nil
	case p.Datum_R_STR:
		return datum.GetRStr(), nil
	case p.Datum_R_ARRAY:
		items := []interface{}{}
		for _, d := range datum.GetRArray() {
			item, err := deconstructDatum(d, opts)
			if err != nil {
				return nil, err
			}
			items = append(items, item)
		}
		return items, nil
	case p.Datum_R_OBJECT:
		obj := map[string]interface{}{}

		for _, assoc := range datum.GetRObject() {
			key := assoc.GetKey()

			val, err := deconstructDatum(assoc.GetVal(), opts)
			if err != nil {
				return nil, err
			}

			obj[string(key)] = val
		}

		pobj, err := convertPseudotype(obj, opts)
		if err != nil {
			return nil, err
		}

		return pobj, nil
	}

	return nil, fmt.Errorf("Unknown Datum type %s encountered in response.", datum.GetType().String())
}
예제 #2
0
// deconstructDatum converts a datum object to an arbitrary type
func deconstructDatum(datum *p.Datum, opts map[string]interface{}) (interface{}, error) {
	switch datum.GetType() {
	case p.Datum_R_NULL:
		return nil, nil
	case p.Datum_R_BOOL:
		return datum.GetRBool(), nil
	case p.Datum_R_NUM:
		return datum.GetRNum(), nil
	case p.Datum_R_STR:
		return datum.GetRStr(), nil
	case p.Datum_R_ARRAY:
		items := []interface{}{}
		for _, d := range datum.GetRArray() {
			item, err := deconstructDatum(d, opts)
			if err != nil {
				return nil, err
			}
			items = append(items, item)
		}
		return items, nil
	case p.Datum_R_OBJECT:
		obj := map[interface{}]interface{}{}

		for _, assoc := range datum.GetRObject() {
			key := assoc.GetKey()

			val, err := deconstructDatum(assoc.GetVal(), opts)
			if err != nil {
				return nil, err
			}

			obj[key] = val
		}

		// Handle ReQL pseudo-types
		if reqlType, ok := obj["$reql_type$"]; ok {
			if reqlType == "TIME" {
				// load timeformat, set to native if the option was not set
				timeFormat := "native"
				if opt, ok := opts["time_format"]; ok {
					if sopt, ok := opt.(string); ok {
						timeFormat = sopt
					} else {
						return nil, fmt.Errorf("Invalid time_format run option \"%s\".", opt)
					}
				}

				if timeFormat == "native" {
					return reqlTimeToNativeTime(obj["epoch_time"].(float64), obj["timezone"].(string))
				} else if timeFormat == "raw" {
					return obj, nil
				} else {
					return nil, fmt.Errorf("Unknown time_format run option \"%s\".", reqlType)
				}
			} else {
				return obj, nil
			}
		}

		return obj, nil
	}

	return nil, fmt.Errorf("Unknown Datum type %s encountered in response.", datum.GetType().String())
}