// 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 }
// 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) }
// 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()) }