// marshalValue returns a proto.Value initialized from the source // reflect.Value, returning an error if the types are not compatible. func marshalValue(v interface{}) (proto.Value, error) { var r proto.Value if v == nil { return r, nil } switch t := v.(type) { case nil: return r, nil case string: r.SetBytes([]byte(t)) return r, nil case []byte: r.SetBytes(t) return r, nil case proto.Key: r.SetBytes([]byte(t)) return r, nil case time.Time: err := r.SetTime(t) return r, err case gogoproto.Message: err := r.SetProto(t) return r, err } switch v := reflect.ValueOf(v); v.Kind() { case reflect.Bool: i := int64(0) if v.Bool() { i = 1 } r.SetInt(i) return r, nil case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: r.SetInt(v.Int()) return r, nil case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: r.SetInt(int64(v.Uint())) return r, nil case reflect.Float32, reflect.Float64: r.SetFloat(v.Float()) return r, nil case reflect.String: r.SetBytes([]byte(v.String())) return r, nil } return r, fmt.Errorf("unable to marshal value: %s", v) }
// GetInitialSystemValues returns a list of key/value pairs. // They are written at cluster bootstrap time (see storage/node.go:BootstrapCLuster). func GetInitialSystemValues() []proto.KeyValue { systemData := []struct { parentID ID desc descriptorProto }{ {keys.RootNamespaceID, &SystemDB}, {SystemDB.ID, &NamespaceTable}, {SystemDB.ID, &DescriptorTable}, {SystemDB.ID, &UsersTable}, {SystemDB.ID, &ZonesTable}, } // Initial kv pairs: // - ID generator // - 2 per table/database numEntries := 1 + len(systemData)*2 ret := make([]proto.KeyValue, numEntries, numEntries) i := 0 // Descriptor ID generator. value := proto.Value{} value.SetInt(int64(keys.MaxReservedDescID + 1)) ret[i] = proto.KeyValue{ Key: keys.DescIDGenerator, Value: value, } i++ // System database and tables. for _, d := range systemData { value = proto.Value{} value.SetInt(int64(d.desc.GetID())) ret[i] = proto.KeyValue{ Key: MakeNameMetadataKey(d.parentID, d.desc.GetName()), Value: value, } i++ value = proto.Value{} if err := value.SetProto(d.desc); err != nil { log.Fatalf("could not marshal %v", d.desc) } ret[i] = proto.KeyValue{ Key: MakeDescMetadataKey(d.desc.GetID()), Value: value, } i++ } return ret }
// marshalValue returns a proto.Value initialized from the source // interface{}, returning an error if the types are not compatible. func marshalValue(v interface{}) (proto.Value, error) { var r proto.Value // Handle a few common types via a type switch. switch t := v.(type) { case nil: return r, nil case bool: i := int64(0) if t { i = 1 } r.SetInt(i) return r, nil case string: r.SetBytes([]byte(t)) return r, nil case []byte: r.SetBytes(t) return r, nil case proto.Key: r.SetBytes([]byte(t)) return r, nil case time.Time: r.SetTime(t) return r, nil case gogoproto.Message: err := r.SetProto(t) return r, err } // Handle all of the Go primitive types besides struct and pointers. This // switch also handles types based on a primitive type (e.g. "type MyInt // int"). switch v := reflect.ValueOf(v); v.Kind() { case reflect.Bool: i := int64(0) if v.Bool() { i = 1 } r.SetInt(i) return r, nil case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: r.SetInt(v.Int()) return r, nil case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: r.SetInt(int64(v.Uint())) return r, nil case reflect.Float32, reflect.Float64: r.SetFloat(v.Float()) return r, nil case reflect.String: r.SetBytes([]byte(v.String())) return r, nil } return r, fmt.Errorf("unable to marshal value: %s", v) }