go-gorm / gorm

The fantastic ORM library for Golang, aims to be developer friendly
https://gorm.io
MIT License
37.02k stars 3.94k forks source link

Error Not Found but not return error in gorm postgresql #7273

Closed adhiva closed 1 week ago

adhiva commented 1 week ago

Your Question

Is my code wrong ? Because I try to get some value in DB PostgreSQL but doesn't return errNotFound my err variable still

The document you expected this should be explained

Expected answer

Please return error when record not found from my query.

package main

import (
    "fmt"
    "gorm.io/driver/sqlite"
    "gorm.io/gorm"
)

type Product struct {
    ID         uint
    CategoryID uint
    Name       string
    ProductType string
    Sequence   int
    Variants   []Product
    Parent     *Product
}

func main() {
    db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
    if err != nil {
        panic("failed to connect to database")
    }

    // Initialize tables and sample data
    db.AutoMigrate(&Product{})

    var products []Product
    var total int64

    // Sample input struct for filtering
    productFilter := struct {
        ID         uint
        CategoryID uint
        ProductType string
        IncludeVariants bool
        IncludeParent   bool
    }{
        ProductType: "electronic",
        ID:          0,
        CategoryID:  0,
        IncludeVariants: true,
        IncludeParent:   true,
    }

    tx := db.Begin()

    // Applying conditional filters
    if productFilter.ProductType != "" {
        tx = tx.Where("? = ANY(product_type)", productFilter.ProductType)
    }

    if productFilter.ID != 0 && productFilter.CategoryID != 0 {
        // If both ID and CategoryID are set, use OR and wrap in parentheses
        tx = tx.Where("(id = ? OR category_id = ?)", productFilter.ID, productFilter.CategoryID)
    } else if productFilter.ID != 0 {
        // If only ID is set, use AND
        tx = tx.Where("id = ?", productFilter.ID)
    } else if productFilter.CategoryID != 0 {
        // If only CategoryID is set, use AND
        tx = tx.Where("category_id = ?", productFilter.CategoryID)
    } else {
        // If neither ID nor CategoryID are set, filter for NULL
        tx = tx.Where("category_id IS NULL")
    }

    if productFilter.IncludeVariants {
        tx = tx.Preload("Variants")
    }

    if productFilter.IncludeParent {
        tx = tx.Preload("Parent")
    }

    if productFilter.ProductType == "electronic" {
        tx.Order("CASE WHEN name = 'Premium' THEN 0 ELSE 1 END")
    }

    txCount := tx
    txCount.Model(&products).Count(&total)
    if err = tx.Order("sequence ASC").Find(&products).Error; err != nil {
        fmt.Println("Error:", err)
        tx.Rollback()
        txCount.Rollback()
        return
    }

    fmt.Println("Total:", total)
    fmt.Println("Results:", products)
}
adhiva commented 1 week ago

It's same with this https://github.com/go-gorm/gorm/issues/6105