-
Notifications
You must be signed in to change notification settings - Fork 51
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
UpdateMatching does not support custom StorerIndexFunc #110
Comments
Do you have an actual issue you are running into with a replicatible code snippet? The Storer interface doesn't actually define any decoding or encoding, it just deals with returning bytes from a type so you can define anything that describes the atomic instance of your type; i.e. what makes this item unique. The assumption is that the same decoder and encoder you specify in your DB connection options would be used in your custom Storer implementation using the default AnonStorer as an example as to how to implement it: storer.indexes[indexName] = Index{
IndexFunc: func(name string, value interface{}) ([]byte, error) {
tp := reflect.ValueOf(value)
for tp.Kind() == reflect.Ptr {
tp = tp.Elem()
}
return s.encode(tp.FieldByName(name).Interface())
},
Unique: unique,
} So I'm trying to understand what scenario you're trying to solve where you are using a different encoder / decoder for your indexes then for the rest of your data? |
Hi , I try to customize the type Sample struct {
Id uint32
}
func (t *Sample) Type() string {
return "Sample"
}
func (t *Sample) Indexes() map[string]badgerhold.Index {
return sampleIndex
}
sampleIndex := make(map[string]badgerhold.Index)
sampleIndex["Id"] = badgerhold.Index{
IndexFunc: func(name string, value interface{}) ([]byte, error) {
if t, ok := value.(*Sample); ok {
return badgerhold.DefaultEncode(t.Id) // <- works fine
// id := make([]byte, 4) // <- did not work here
// binary.LittleEndian.PutUint32(id, t.Id)
// return id, nil
}
return nil, errors.New("error")
},
} |
Sorry, I don't get you, Since the If I understand |
From https://pkg.go.dev/github.com/timshannon/badgerhold#Storer
Because it needs to match the same encoding as the rest of the database so that values can be properly compared. It's kind of like saying "why can't I compare the word four and the number 4. They are the same value." They may both represent the same value, but they are encoding that value in different ways. In order for the database to store things in order for quick searching, all values need to be encoded the same. binary.LittleEndian.PutUint32(id, t.Id) and Gob encode return two very different byte arrays. |
Yes, I understand what you said. But, what I want to express is that when Did I miss something? |
I may be missing something too, or missunderstanding what you're trying to accomplish. the default / example As long as you decode your values before returning them in your custom Storer type everything should be fine. However I don't believe have any tests confirming that to be true. If you have a code snippet that shows otherwise, please share it. The previous one you sent was not encoding the index values correctly, it was using an entirely different encoding, and thus will not work. I do acknowledge, however, that the Storer interface is a bit of a leaky abstraction, and relies on too much required behavior to be implemented to work properly. If I were re-doing it now, I would completely change it. However doing so now would be backwards incompatible, and I'm not sure such a huge breaking change is worth it to simply clarify the interface. |
When using an index,
UpdateMatching
creates an Iterator to query all index keys and usesmatchsAllCriteria
to compare whether the index meets the query criteria. Then, decode the valuekey[len(prefix):]
for matchingBut
Criterion.test
always uses Default Decode.While
indexUpdate
uses a custom Storer IndexFunc.The text was updated successfully, but these errors were encountered: