go-gorm / postgres

GORM PostgreSQL driver
MIT License
225 stars 119 forks source link

Custom naming strategies no longer work with changes from PR-232/ISSUE-191 #255

Closed recck closed 5 months ago

recck commented 6 months ago

Description

Providing a custom naming strategy when opening a new GORM connection encounters a panic.

Example naming strategy:

package repository

import (
    "fmt"
    "gorm.io/gorm/schema"
    "slices"
    "strings"
    "unicode"
)

type DbNamingStrategy struct {
}

func (a DbNamingStrategy) UniqueName(table, column string) string {
    return fmt.Sprintf("%s_%s_uniq", table, column)
}

func (DbNamingStrategy) lowerFirst(s string) string {
    r := []rune(s)
    r[0] = unicode.ToLower(r[0])

    return string(r)
}

// TableName will return a lowercase-first table name (i.e. camelCase)
func (a DbNamingStrategy) TableName(table string) string {
    if table == "" {
        return ""
    }

    return a.lowerFirst(table)
}

func (a DbNamingStrategy) SchemaName(table string) string {
    return table
}

// ColumnName will either return a lowercase-first column name, or an all lowercase name if the input is all uppercase
func (a DbNamingStrategy) ColumnName(table, column string) string {
    if strings.ToUpper(column) == column {
        return strings.ToLower(column)
    }

    return a.lowerFirst(column)
}

func (a DbNamingStrategy) JoinTableName(joinTable string) string {
    return a.lowerFirst(joinTable)
}

func (a DbNamingStrategy) RelationshipFKName(relationship schema.Relationship) string {
    return fmt.Sprintf("%s_%s_fkey", a.lowerFirst(relationship.Schema.Table), a.lowerFirst(relationship.Name))
}

func (a DbNamingStrategy) CheckerName(table, column string) string {
    return fmt.Sprintf("%s_%s_chk", table, column)
}

func (a DbNamingStrategy) IndexName(table, column string) string {
    return fmt.Sprintf("%s_%s_idx", table, column)
}

Example using it to open a new GORM connection:

db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{
    NamingStrategy:         repository.DbNamingStrategy{},
})

The changes in #232 only assume the naming strategy to be an instance of schema.NamingStrategy, a reference to a schema.NamingStrategy or nil. Therefore it does not encounter any matching case in the switch statement leaving the variable namingStartegy initialized to nil and trying to access the IdentifierMaxLength property on it causes a panic.

DAcodedBEAT commented 5 months ago

@go-gorm Can we have someone look into this issue?