Ejemplo n.º 1
0
// mustGetInteger decodes an int64 value from the bytes field of the receiver
// and panics if the bytes field is not 0 or 8 bytes in length.
func mustGetInteger(v *proto.Value) int64 {
	i, err := v.GetInteger()
	if err != nil {
		panic(err)
	}
	return i
}
Ejemplo n.º 2
0
// ConditionalPut sets the value for a specified key only if
// the expected value matches. If not, the return value contains
// the actual value.
func (mvcc *MVCC) ConditionalPut(key Key, timestamp proto.Timestamp, value proto.Value, expValue *proto.Value, txn *proto.Transaction) (*proto.Value, error) {
	// Handle check for non-existence of key. In order to detect
	// the potential write intent by another concurrent transaction
	// with a newer timestamp, we need to use the max timestamp
	// while reading.
	existVal, err := mvcc.Get(key, proto.MaxTimestamp, txn)
	if err != nil {
		return nil, err
	}

	if expValue == nil && existVal != nil {
		return existVal, util.Errorf("key %q already exists", key)
	} else if expValue != nil {
		// Handle check for existence when there is no key.
		if existVal == nil {
			return nil, util.Errorf("key %q does not exist", key)
		} else if expValue.Bytes != nil && !bytes.Equal(expValue.Bytes, existVal.Bytes) {
			return existVal, util.Errorf("key %q does not match existing", key)
		} else if expValue.Integer != nil && (existVal.Integer == nil || expValue.GetInteger() != existVal.GetInteger()) {
			return existVal, util.Errorf("key %q does not match existing", key)
		}
	}

	return nil, mvcc.Put(key, timestamp, value, txn)
}
Ejemplo n.º 3
0
// unmarshalValue sets the destination reflect.Value contents from the source
// proto.Value, returning an error if the types are not compatible.
func unmarshalValue(src *proto.Value, dest reflect.Value) error {
	if src == nil {
		dest.Set(reflect.Zero(dest.Type()))
		return nil
	}

	switch d := dest.Addr().Interface().(type) {
	case *string:
		if src.Bytes != nil {
			*d = string(src.Bytes)
		} else {
			*d = ""
		}
		return nil

	case *[]byte:
		if src.Bytes != nil {
			*d = src.Bytes
		} else {
			*d = nil
		}
		return nil

	case *gogoproto.Message:
		panic("TODO(pmattis): unimplemented")

	case *encoding.BinaryUnmarshaler:
		return (*d).UnmarshalBinary(src.Bytes)
	}

	switch dest.Kind() {
	case reflect.Bool:
		i, err := src.GetInteger()
		if err != nil {
			return err
		}
		dest.SetBool(i != 0)
		return nil

	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		i, err := src.GetInteger()
		if err != nil {
			return err
		}
		dest.SetInt(i)
		return nil

	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
		i, err := src.GetInteger()
		if err != nil {
			return err
		}
		dest.SetUint(uint64(i))
		return nil

	case reflect.Float32, reflect.Float64:
		i, err := src.GetInteger()
		if err != nil {
			return err
		}
		dest.SetFloat(math.Float64frombits(uint64(i)))
		return nil

	case reflect.String:
		if src == nil || src.Bytes == nil {
			dest.SetString("")
			return nil
		}
		dest.SetString(string(src.Bytes))
		return nil
	}

	return fmt.Errorf("unable to unmarshal value: %s", dest.Type())
}