Repository: go-gorm/gorm

Issue #6105: ErrRecordNotFound not work for Find()?
Created: 2023-02-25T09:27:08Z
GORM Playground Link

go-gorm/playground#573
run test code below can reproduce this
Do I miss something configuration of gorm.Config, which cause this problem or what is the best practice to use ErrRecordNotFound ?
package main

import (
	"errors"
	"fmt"
	"log"
	"strings"

	"gorm.io/driver/sqlite"
	// "gorm.io/driver/mysql"
	"gorm.io/gorm"
	"gorm.io/gorm/schema"
)

type Records struct {
	RID   int `gorm:"primaryKey"`
	Name  string
	Price float64
}

type MyStrategy struct {
	schema.NamingStrategy
}

func (s MyStrategy) ColumnName(table, column string) string {
	return strings.ToLower(column)
}

func main() {
	db, err := gorm.Open(sqlite.Open("gorm1.db"), &gorm.Config{
		NamingStrategy: MyStrategy{},
	})
	if err != nil {
		log.Fatalln(err)
	}

	r := []*Records{}
	if !db.Migrator().HasTable(r) {
		if err := db.Migrator().CreateTable(r); err != nil {
			log.Fatalln(err)
		} else {
			fmt.Println("create table ok")
			records := make([]Records, 5)
			for i := range records {
				records[i] = Records{RID: i + 1, Name: fmt.Sprintf("name-%v", i), Price: float64(i) + 1.2}
			}
			fmt.Println(&records)
			db.Create(&records)
			fmt.Println("after insert", &records)
		}
	} else { // has table, do query and then update
		gormDb := db.Where("price > 100").Find(&r)
		fmt.Println("rows =", gormDb.RowsAffected, gormDb.Error)

                // FIXME 
		if errors.Is(gormDb.Error, gorm.ErrRecordNotFound) {
			fmt.Println("record not found")
		}

		// query
		var result []Records
		gormDb.Scan(&result)
		for _, r := range result {
			fmt.Printf("item %v %v, %v\n", r.RID, r.Name, r.Price)
		}
	}
}

Duplicate issue #6158: Searching for a nonexistent record does not return `ErrRecordNotFound`
Created: 2023-03-16T16:24:32Z
When I search for a nonexistent record, no error is returned, while I expect for ErrRecordNotFound
here is an example:
package main

import (
	"errors"
	"fmt"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"time"
)

var Db *gorm.DB

type VModel struct {
	ID        uint64    `gorm:"index:id; primarykey, autoIncrement"`
	CreatedAt time.Time `gorm:"autoCreateTime"`
	UpdatedAt time.Time
	DeletedAt gorm.DeletedAt
}

type Archive struct {
	VModel
	Path     string `gorm:"index:path;type:varchar(100)"`
	Password string `gorm:"type:varchar(10)"`
}

func main() {
	dsn := "MYSQL_CONNECTION_STRING"
	Db, _ = gorm.Open(mysql.Open(dsn), &gorm.Config{})

	t := Archive{}
	err := Db.Model(&Archive{}).Where("path = ?", "/root").Find(&t).Error
	fmt.Println(errors.Is(err, gorm.ErrRecordNotFound))
	fmt.Println(err) 
        fmt.Printf("%+v", t)
}

Here is the SQL that creates the table:
CREATE TABLE `archives` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `created_at` datetime(3) DEFAULT NULL,
  `updated_at` datetime(3) DEFAULT NULL,
  `deleted_at` datetime(3) DEFAULT NULL,
  `path` varchar(100) DEFAULT NULL,
  `password` varchar(10) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `id` (`id`),
  KEY `path` (`path`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

And you do not have to insert any data into the table, just run the code above and the output will be like following:
false
<nil>
{VModel:{ID:0 CreatedAt:0001-01-01 00:00:00 +0000 UTC UpdatedAt:0001-01-01 00:00:00 +0000 UTC DeletedAt:{Time:0001-01-01 00:00:00 +0000 UTC Valid:false}} Path: Password:}

On the one hand, no error is returned, on the other hand, the returned t is an empty struct. Is there anything I missed?

Closing comment (2023-03-17T02:09:05Z): Same as #6105

Thank you