Ejemplo n.º 1
0
func encUUID(v interface{}) (driver.Value, error) {
	var u uuid.UUID
	switch v := v.(type) {
	case string:
		var err error
		u, err = uuid.ParseUUID(v)
		if err != nil {
			return nil, err
		}
	case []byte:
		u = uuid.FromBytes(v)
	case uuid.UUID:
		u = v
	default:
		return nil, fmt.Errorf("can not convert %T to a UUID", v)
	}
	return u.Bytes(), nil
}
Ejemplo n.º 2
0
func decode(b []byte, t []uint16) driver.Value {
	switch t[0] {
	case typeBool:
		if len(b) >= 1 && b[0] != 0 {
			return true
		}
		return false
	case typeBlob:
		return b
	case typeVarchar, typeText, typeAscii:
		return b
	case typeInt:
		return int64(int32(binary.BigEndian.Uint32(b)))
	case typeBigInt:
		return int64(binary.BigEndian.Uint64(b))
	case typeFloat:
		return float64(math.Float32frombits(binary.BigEndian.Uint32(b)))
	case typeDouble:
		return math.Float64frombits(binary.BigEndian.Uint64(b))
	case typeTimestamp:
		t := int64(binary.BigEndian.Uint64(b))
		sec := t / 1000
		nsec := (t - sec*1000) * 1000000
		return time.Unix(sec, nsec)
	case typeUUID, typeTimeUUID:
		return uuid.FromBytes(b)
	case typeMap:
		// A Map is stored as the number of tuples followed by the sequence of tuples.
		// Each name and value are stored as a byte count followed by the raw bytes.
		//
		// Example:
		// 0 23 - 0 3 - 1 2 3 - 0 1 - 66 .... repeats
		//
		// In this example, there are 23 tuples. The first tuple's name has 3 bytes,
		// which are 1, 2, and 3, and the tuple's value has 1 byte, which is 66.
		//
		// It only supports map[string][string] right now.
		if t[1] == typeVarchar && t[2] == typeVarchar {
			// Read the number of tuples
			collLen := int(binary.BigEndian.Uint16(b[:2]))
			coll := make(map[string]string, collLen)

			for pairNum, bpointer := 0, 2; pairNum < collLen; pairNum++ {
				// Read the byte count for the tuple's name
				keyLen := int(binary.BigEndian.Uint16(b[bpointer : bpointer+2]))
				bpointer += 2
				// Read the tuple's name according to the byte count
				key := string(b[bpointer : bpointer+keyLen])
				bpointer += keyLen

				// Read the byte count for the tuple's value
				valueLen := int(binary.BigEndian.Uint16(b[bpointer : bpointer+2]))
				bpointer += 2
				// Read the tuple's value according to the byte count
				value := string(b[bpointer : bpointer+valueLen])
				bpointer += valueLen

				coll[key] = value
			}

			return coll
		} else {
			panic("unsupported map collection type")
		}
	default:
		panic("unsupported type")
	}
	return b
}