package boltease import ( "errors" "fmt" "reflect" "unicode" "unicode/utf8" ) type any = interface{} /* func (b *DB) Save(path []string, key string, src any) error { t := reflect.TypeOf(src) if t.Kind() == reflect.Pointer { // Save the actual struct elem := reflect.ValueOf(src).Elem() return b.Save(path, key, elem.Interface()) } if t.Kind() == reflect.Struct { fields := reflect.VisibleFields(t) r := reflect.ValueOf(src) for _, fld := range fields { f := r.FieldByName(fld.Name) if (f.Kind() == reflect.Struct || f.Kind() == reflect.Pointer) && f != src { if f.CanInterface() { err := b.Save(append(path, FieldName(fld)), f.Interface()) if err != nil { return err } } else { err := b.Save(append(path, FieldName(fld)), reflect.Indirect(f)) if err != nil { return err } } } else { if err := b.Set(path, FieldName(fld), f); err != nil { return err } } } } else { return b.Set(path[:len(path)-1], path[len(path)-1], src) } return nil } */ func (b *DB) LoadOld(path []string, dest any) error { destValue := reflect.ValueOf(dest) fmt.Println("Loading:", path, destValue) if destValue.Kind() != reflect.Pointer { return errors.New("Destination must be a pointer") } d := reflect.Indirect(destValue) fmt.Println(">> d.Kind() ->", d.Kind()) if d.Kind() != reflect.Struct { if b.CanGetForInterface(d) { fmt.Println(">> Kind != Struct; GetForInterface") path, name := path[:len(path)-1], path[len(path)-1] return b.GetForInterface(path, name, dest) } else { fmt.Println(">> Reflect Indirect(d) Elem") dest = reflect.Indirect(d).Elem() fmt.Println(">> Dest set") } } entityType := reflect.TypeOf(dest).Elem() fmt.Println(">> entityType.Kind() ->", entityType.Kind()) var ret error for i := 0; i < entityType.NumField(); i++ { structFld := entityType.Field(i) fldName := FieldName(structFld) fmt.Println("Loading Field:", fldName, "->", structFld.Type.Kind()) switch structFld.Type.Kind() { case reflect.Pointer, reflect.Struct: fmt.Println("Getting Pointer or Struct") var wrk interface{} var wrkV reflect.Value if structFld.Type.Kind() == reflect.Pointer { fmt.Println(" It's a pointer to something") wrkV = reflect.New(structFld.Type).Elem() } else { fmt.Println(" It's a struct itself") wrkV = reflect.New(reflect.TypeOf(structFld)) } wrk = wrkV.Interface() fmt.Println("-> Recurse (struct)", reflect.TypeOf(wrk)) return errors.New("Recursive Loading not Implemented") err := b.Load(append(path, fldName), &wrk) if err != nil { fmt.Println("-> -> Error loading.", err.Error()) if ret == nil { ret = err } } else { // Set the value reflect.ValueOf(dest).Elem().FieldByName(structFld.Name).Set(reflect.ValueOf(wrk)) } case reflect.String: fmt.Println("Getting String") var wrk string err := b.GetForInterface(path, fldName, &wrk) if err != nil { if ret == nil { ret = err } } else { // Set the value reflect.ValueOf(dest).Elem().FieldByName(structFld.Name).Set(reflect.ValueOf(wrk)) } case reflect.Bool: fmt.Println("Getting Boolean") var wrk bool err := b.GetForInterface(path, fldName, &wrk) if err != nil { if ret == nil { ret = err } } else { // Set the value reflect.ValueOf(dest).Elem().FieldByName(structFld.Name).Set(reflect.ValueOf(wrk)) } case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: fmt.Println("Getting Integer") var wrk int err := b.GetForInterface(path, fldName, &wrk) if err != nil { if ret == nil { ret = err } } else { // Set the value reflect.ValueOf(dest).Elem().FieldByName(structFld.Name).Set(reflect.ValueOf(wrk)) } } /* setField := reflect.ValueOf(dest).Elem().Field(i) value := entityType.Field(i) fldName := FieldName(value) if value.Type.Kind() == reflect.Struct { b.LoadStruct(append(path, fldName), setField.Interface()) } else { err := b.GetForInterface(path, fldName, &value) if err != nil { fmt.Println(err) return err } fmt.Println("value:", value) } */ /* if value.Type.Kind() == reflect.Struct { b.LoadStruct(append(path, fldName), setField.Interface()) } else { v, err := b.GetForType(path, fldName, value) if err != nil { return err } setField.Set(reflect.ValueOf(v)) } */ } return ret } func (b *DB) loadObject(path []string, v reflect.Value) error { //var fields structFields //switch v.Kind() { //case reflect.Struct: // fields = cachedTypeFields(t) //} //return nil return errors.New("Load Object not Implemented") } func FieldName(fld reflect.StructField) string { nm := fld.Name tag := fld.Tag.Get("boltease") if tag != "" { nm = tag } return nm } func FieldIgnored(fld reflect.StructField) bool { return fld.Tag.Get("boltease") == "-" } func ReflectValueToInterface(val reflect.Value) interface{} { switch val.Kind() { case reflect.Pointer: return ReflectValueToInterface(reflect.Indirect(val)) case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return val.Int() case reflect.Bool: return val.Bool() case reflect.String: return val.String() default: return val.Bytes() } } // foldName returns a folded string such that foldName(x) == foldName(y) // is identical to bytes.EqualFold(x, y). func foldName(in []byte) []byte { // This is inlinable to take advantage of "function outlining". var arr [32768]byte // The max size of a bolt key return appendFoldedName(arr[:0], in) } func appendFoldedName(out, in []byte) []byte { for i := 0; i < len(in); { // Handle single-byte ASCII. if c := in[i]; c < utf8.RuneSelf { if 'a' <= c && c <= 'z' { c -= 'a' - 'A' } out = append(out, c) i++ continue } // Handle multi-byt eUnicode. r, n := utf8.DecodeRune(in[i:]) out = utf8.AppendRune(out, foldRune(r)) i += n } return out } // foldRune returns the smallest rune for all runes in the same fold set. func foldRune(r rune) rune { for { r2 := unicode.SimpleFold(r) if r2 <= r { return r2 } r = r2 } }