timshannon / bolthold

BoltHold is an embeddable NoSQL store for Go types built on BoltDB
MIT License
648 stars 46 forks source link

foreach can't use, when the key's type is uint64 #136

Closed l1351868270 closed 2 years ago

l1351868270 commented 2 years ago

I want to use the autoincrementing integer. So i write the unittest in "foreach_test.go":

func TestForEachKeyNextSequence(t *testing.T) {
    // go test -v -test.run TestForEachKeyNextSequence
    testWrap(t, func(store *bolthold.Store, t *testing.T) {
        type KeyTest struct {
            Key   int `boltholdKey:"Key"`
            Value string
        }

        err := store.Insert(bolthold.NextSequence(), &KeyTest{
            Value: "test value",
        })

        if err != nil {
            t.Fatalf("Error inserting KeyTest struct for Key struct tag testing. Error: %s", err)
        }

        err = store.ForEach(bolthold.Where(bolthold.Key).Ne(int(100)), func(result *KeyTest) error {
            t.Log(result)
            // if result.Key != key {
            //  t.Fatalf("Key struct tag was not set correctly.  Expected %d, got %d", key, result.Key)
            // }
            return nil
        })
        if err != nil {
            t.Fatalf("Error running ForEach in TestForEachKeyNextSequence. ERROR: %s", err)
        }
    })
}

But, it has a error like this

=== RUN   TestForEachKeyNextSequence
    foreach_test.go:174: Error running ForEach in TestForEachKeyNextSequence. ERROR: gob: decoding into local type *int, received remote type uint
--- FAIL: TestForEachKeyNextSequence (0.01s)
FAIL
exit status 

ps: It is also incorrect when i use the key, when it's type is uint64. The error is same.

func TestForEachKeyUint64(t *testing.T) {
    // go test -v -test.run TestForEachKeyUint64
    testWrap(t, func(store *bolthold.Store, t *testing.T) {
        type KeyTest struct {
            Key   int `boltholdKey:"Key"`
            Value string
        }

        err := store.Insert(uint64(4), &KeyTest{
            Value: "test value",
        })

        if err != nil {
            t.Fatalf("Error inserting KeyTest struct for Key struct tag testing. Error: %s", err)
        }

        err = store.ForEach(bolthold.Where(bolthold.Key).Ne(int(100)), func(result *KeyTest) error {
            t.Log(result)
            // if result.Key != key {
            //  t.Fatalf("Key struct tag was not set correctly.  Expected %d, got %d", key, result.Key)
            // }
            return nil
        })
        if err != nil {
            t.Fatalf("Error running ForEach in TestForEachKeyNextSequence. ERROR: %s", err)
        }
    })
}
timshannon commented 2 years ago

bolt generated key types are uint64s, so you need to change you type to uint/uint64 in your struct

type KeyTest struct {
            Key   uint `boltholdKey:"Key"`
            Value string
        }

Alternately, you could use a more flexible encoder than gob. For example, if you use JSON, it may be able to make that conversion.