storm icon indicating copy to clipboard operation
storm copied to clipboard

Fetch object by ID failed

Open hex2010 opened this issue 6 years ago • 4 comments

package main

import (
	"log"
	"os"

	"github.com/asdine/storm"
)

type A struct {
	Name string `storm:"id"`
	ID   string
}

func main() {
	db, err := storm.Open("test.db")
	defer func() {
		db.Close()
		os.Remove("test.db")
	}()

	if err != nil {
		log.Fatal(err)
	}
	if err = db.Init(&A{}); err != nil {
		log.Fatal(err)
	}
	if err = db.Save(&A{Name: "Tom", ID: "123"}); err != nil {
		log.Fatal(err)
	}

	var list []A
	if err = db.Select().Find(&list); err != nil {
		log.Fatal("Select: ", err)
	}
	log.Printf("Select: %#v", list)

	list = nil
	if err = db.Find("ID", "123", &list); err != nil {
		log.Fatal("Find: ", err)
	}

	log.Printf("Find: %#v", list)
}

test $ go run test.go
2018/05/02 13:32:16 Select: []main.A{main.A{Name:"Tom", ID:"123"}}
2018/05/02 13:32:16 Find: not found
exit status 1

hex2010 avatar May 02 '18 13:05 hex2010

Find takes the field name:

err := db.Find("Name", "123", &list)

asdine avatar May 02 '18 14:05 asdine

type A struct {
	Name string `storm:"id"`
	ID   string
}
main.A{Name:"Tom", ID:"123"}

in this case, "123" is stored in second field, named "ID"

hex2010 avatar May 03 '18 13:05 hex2010

Hi,

I've a similar test case when I try to use One() with a uint64 field. Using One() returns a not found err, using Select().First() returns the entry.

package main

import (
	"log"
	"os"

	"github.com/asdine/storm"
	"github.com/asdine/storm/q"
)

type A struct {
	ID  uint64 `storm:"id,increment"`
	Foo string
	Bar uint64
}

func main() {
	db, err := storm.Open("test.db")
	defer func() {
		db.Close()
		os.Remove("test.db")
	}()

	if err != nil {
		log.Fatal(err)
	}
	if err = db.Init(&A{}); err != nil {
		log.Fatal(err)
	}
	if err = db.Save(&A{Foo: "FOO", Bar: 42}); err != nil {
		log.Fatal(err)
	}

	var a A
	if err = db.Select(q.Eq("Bar", 42)).First(&a); err != nil {
		log.Fatal("Select: ", err)
	}
	log.Printf("Select: %#v", a)

	var b A
	if err = db.One("Bar", 42, &b); err != nil {
		log.Fatal("One: ", err)
	}
	log.Printf("One: %#v", b)

}
$ go run main.go
2019/10/23 19:08:16 Select: main.A{ID:0x1, Foo:"FOO", Bar:0x2a}
2019/10/23 19:08:16 One: not found
exit status 1

lmeunier avatar Oct 23 '19 17:10 lmeunier

From what I've seen, db.One() uses q.StrictEq() internally. q.StrictEq() uses reflect.DeepEqual() to compare values, and in my case it tries to compare an uint64 to an int which always fail.

If I replace db.One("Bar", 42, &b) with db.One("Bar", uint64(42), &b), I get a result (as expected).

@hex2010, your initial test case is different. It seems that db.Find() only works with indexed field. Could you try to add `storm:"index"` to your ID field?

lmeunier avatar Oct 23 '19 19:10 lmeunier