diff --git a/go.mod b/go.mod index 1cfe5c05..41db9109 100644 --- a/go.mod +++ b/go.mod @@ -37,7 +37,7 @@ require ( gorm.io/datatypes v1.2.6 gorm.io/driver/mysql v1.6.0 gorm.io/driver/sqlite v1.6.0 - gorm.io/gorm v1.30.0 + gorm.io/gorm v1.30.1 ) require ( diff --git a/go.sum b/go.sum index 7de7ba80..b0557ac9 100644 --- a/go.sum +++ b/go.sum @@ -229,5 +229,5 @@ gorm.io/driver/sqlite v1.6.0 h1:WHRRrIiulaPiPFmDcod6prc4l2VGVWHz80KspNsxSfQ= gorm.io/driver/sqlite v1.6.0/go.mod h1:AO9V1qIQddBESngQUKWL9yoH93HIeA1X6V633rBwyT8= gorm.io/driver/sqlserver v1.6.0 h1:VZOBQVsVhkHU/NzNhRJKoANt5pZGQAS1Bwc6m6dgfnc= gorm.io/driver/sqlserver v1.6.0/go.mod h1:WQzt4IJo/WHKnckU9jXBLMJIVNMVeTu25dnOzehntWw= -gorm.io/gorm v1.30.0 h1:qbT5aPv1UH8gI99OsRlvDToLxW5zR7FzS9acZDOZcgs= -gorm.io/gorm v1.30.0/go.mod h1:8Z33v652h4//uMA76KjeDH8mJXPm1QNCYrMeatR0DOE= +gorm.io/gorm v1.30.1 h1:lSHg33jJTBxs2mgJRfRZeLDG+WZaHYCk3Wtfl6Ngzo4= +gorm.io/gorm v1.30.1/go.mod h1:8Z33v652h4//uMA76KjeDH8mJXPm1QNCYrMeatR0DOE= diff --git a/vendor/gorm.io/gorm/callbacks/create.go b/vendor/gorm.io/gorm/callbacks/create.go index d8701f51..cb8429b3 100644 --- a/vendor/gorm.io/gorm/callbacks/create.go +++ b/vendor/gorm.io/gorm/callbacks/create.go @@ -53,9 +53,13 @@ func Create(config *Config) func(db *gorm.DB) { if _, ok := db.Statement.Clauses["RETURNING"]; !ok { fromColumns := make([]clause.Column, 0, len(db.Statement.Schema.FieldsWithDefaultDBValue)) for _, field := range db.Statement.Schema.FieldsWithDefaultDBValue { - fromColumns = append(fromColumns, clause.Column{Name: field.DBName}) + if field.Readable { + fromColumns = append(fromColumns, clause.Column{Name: field.DBName}) + } + } + if len(fromColumns) > 0 { + db.Statement.AddClause(clause.Returning{Columns: fromColumns}) } - db.Statement.AddClause(clause.Returning{Columns: fromColumns}) } } } @@ -122,6 +126,16 @@ func Create(config *Config) func(db *gorm.DB) { pkFieldName = "@id" ) + if db.Statement.Schema != nil { + if db.Statement.Schema.PrioritizedPrimaryField == nil || + !db.Statement.Schema.PrioritizedPrimaryField.HasDefaultValue || + !db.Statement.Schema.PrioritizedPrimaryField.Readable { + return + } + pkField = db.Statement.Schema.PrioritizedPrimaryField + pkFieldName = db.Statement.Schema.PrioritizedPrimaryField.DBName + } + insertID, err := result.LastInsertId() insertOk := err == nil && insertID > 0 @@ -132,14 +146,6 @@ func Create(config *Config) func(db *gorm.DB) { return } - if db.Statement.Schema != nil { - if db.Statement.Schema.PrioritizedPrimaryField == nil || !db.Statement.Schema.PrioritizedPrimaryField.HasDefaultValue { - return - } - pkField = db.Statement.Schema.PrioritizedPrimaryField - pkFieldName = db.Statement.Schema.PrioritizedPrimaryField.DBName - } - // append @id column with value for auto-increment primary key // the @id value is correct, when: 1. without setting auto-increment primary key, 2. database AutoIncrementIncrement = 1 switch values := db.Statement.Dest.(type) { diff --git a/vendor/gorm.io/gorm/generics.go b/vendor/gorm.io/gorm/generics.go index ad2d063f..f3c3e553 100644 --- a/vendor/gorm.io/gorm/generics.go +++ b/vendor/gorm.io/gorm/generics.go @@ -567,7 +567,7 @@ func (g execG[T]) First(ctx context.Context) (T, error) { func (g execG[T]) Scan(ctx context.Context, result interface{}) error { var r T - err := g.g.apply(ctx).Model(r).Find(&result).Error + err := g.g.apply(ctx).Model(r).Find(result).Error return err } diff --git a/vendor/gorm.io/gorm/gorm.go b/vendor/gorm.io/gorm/gorm.go index 67889262..6619f071 100644 --- a/vendor/gorm.io/gorm/gorm.go +++ b/vendor/gorm.io/gorm/gorm.go @@ -137,6 +137,14 @@ func Open(dialector Dialector, opts ...Option) (db *DB, err error) { return isConfig && !isConfig2 }) + if len(opts) > 0 { + if c, ok := opts[0].(*Config); ok { + config = c + } else { + opts = append([]Option{config}, opts...) + } + } + var skipAfterInitialize bool for _, opt := range opts { if opt != nil { diff --git a/vendor/gorm.io/gorm/migrator/migrator.go b/vendor/gorm.io/gorm/migrator/migrator.go index cec4e30f..50a36d10 100644 --- a/vendor/gorm.io/gorm/migrator/migrator.go +++ b/vendor/gorm.io/gorm/migrator/migrator.go @@ -474,7 +474,6 @@ func (m Migrator) MigrateColumn(value interface{}, field *schema.Field, columnTy // found, smart migrate fullDataType := strings.TrimSpace(strings.ToLower(m.DB.Migrator().FullDataTypeOf(field).SQL)) realDataType := strings.ToLower(columnType.DatabaseTypeName()) - var ( alterColumn bool isSameType = fullDataType == realDataType @@ -513,8 +512,19 @@ func (m Migrator) MigrateColumn(value interface{}, field *schema.Field, columnTy } } } + } - // check precision + // check precision + if realDataType == "decimal" || realDataType == "numeric" && + regexp.MustCompile(realDataType+`\(.*\)`).FindString(fullDataType) != "" { // if realDataType has no precision,ignore + precision, scale, ok := columnType.DecimalSize() + if ok { + if !strings.HasPrefix(fullDataType, fmt.Sprintf("%s(%d,%d)", realDataType, precision, scale)) && + !strings.HasPrefix(fullDataType, fmt.Sprintf("%s(%d)", realDataType, precision)) { + alterColumn = true + } + } + } else { if precision, _, ok := columnType.DecimalSize(); ok && int64(field.Precision) != precision { if regexp.MustCompile(fmt.Sprintf("[^0-9]%d[^0-9]", field.Precision)).MatchString(m.DataTypeOf(field)) { alterColumn = true diff --git a/vendor/gorm.io/gorm/schema/field.go b/vendor/gorm.io/gorm/schema/field.go index a6ff1a72..67e60f70 100644 --- a/vendor/gorm.io/gorm/schema/field.go +++ b/vendor/gorm.io/gorm/schema/field.go @@ -448,21 +448,30 @@ func (schema *Schema) ParseField(fieldStruct reflect.StructField) *Field { } // create valuer, setter when parse struct -func (field *Field) setupValuerAndSetter() { +func (field *Field) setupValuerAndSetter(modelType reflect.Type) { // Setup NewValuePool field.setupNewValuePool() // ValueOf returns field's value and if it is zero fieldIndex := field.StructField.Index[0] switch { - case len(field.StructField.Index) == 1 && fieldIndex > 0: - field.ValueOf = func(ctx context.Context, value reflect.Value) (interface{}, bool) { - fieldValue := reflect.Indirect(value).Field(fieldIndex) + case len(field.StructField.Index) == 1 && fieldIndex >= 0: + field.ValueOf = func(ctx context.Context, v reflect.Value) (interface{}, bool) { + v = reflect.Indirect(v) + if v.Type() != modelType { + fieldValue := v.FieldByName(field.Name) + return fieldValue.Interface(), fieldValue.IsZero() + } + fieldValue := v.Field(fieldIndex) return fieldValue.Interface(), fieldValue.IsZero() } default: field.ValueOf = func(ctx context.Context, v reflect.Value) (interface{}, bool) { v = reflect.Indirect(v) + if v.Type() != modelType { + fieldValue := v.FieldByName(field.Name) + return fieldValue.Interface(), fieldValue.IsZero() + } for _, fieldIdx := range field.StructField.Index { if fieldIdx >= 0 { v = v.Field(fieldIdx) @@ -504,13 +513,20 @@ func (field *Field) setupValuerAndSetter() { // ReflectValueOf returns field's reflect value switch { - case len(field.StructField.Index) == 1 && fieldIndex > 0: - field.ReflectValueOf = func(ctx context.Context, value reflect.Value) reflect.Value { - return reflect.Indirect(value).Field(fieldIndex) + case len(field.StructField.Index) == 1 && fieldIndex >= 0: + field.ReflectValueOf = func(ctx context.Context, v reflect.Value) reflect.Value { + v = reflect.Indirect(v) + if v.Type() != modelType { + return v.FieldByName(field.Name) + } + return v.Field(fieldIndex) } default: field.ReflectValueOf = func(ctx context.Context, v reflect.Value) reflect.Value { v = reflect.Indirect(v) + if v.Type() != modelType { + return v.FieldByName(field.Name) + } for idx, fieldIdx := range field.StructField.Index { if fieldIdx >= 0 { v = v.Field(fieldIdx) diff --git a/vendor/gorm.io/gorm/schema/schema.go b/vendor/gorm.io/gorm/schema/schema.go index db236797..2a5c28e2 100644 --- a/vendor/gorm.io/gorm/schema/schema.go +++ b/vendor/gorm.io/gorm/schema/schema.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "go/ast" + "path" "reflect" "strings" "sync" @@ -247,7 +248,7 @@ func ParseWithSpecialTableName(dest interface{}, cacheStore *sync.Map, namer Nam schema.FieldsByBindName[bindName] = field } - field.setupValuerAndSetter() + field.setupValuerAndSetter(modelType) } prioritizedPrimaryField := schema.LookUpField("id") @@ -313,8 +314,14 @@ func ParseWithSpecialTableName(dest interface{}, cacheStore *sync.Map, namer Nam for _, cbName := range callbackTypes { if methodValue := callBackToMethodValue(modelValue, cbName); methodValue.IsValid() { switch methodValue.Type().String() { - case "func(*gorm.DB) error": // TODO hack - reflect.Indirect(reflect.ValueOf(schema)).FieldByName(string(cbName)).SetBool(true) + case "func(*gorm.DB) error": + expectedPkgPath := path.Dir(reflect.TypeOf(schema).Elem().PkgPath()) + if inVarPkg := methodValue.Type().In(0).Elem().PkgPath(); inVarPkg == expectedPkgPath { + reflect.Indirect(reflect.ValueOf(schema)).FieldByName(string(cbName)).SetBool(true) + } else { + logger.Default.Warn(context.Background(), "In model %v, the hook function `%v(*gorm.DB) error` has an incorrect parameter type. The expected parameter type is `%v`, but the provided type is `%v`.", schema, cbName, expectedPkgPath, inVarPkg) + // PASS + } default: logger.Default.Warn(context.Background(), "Model %v don't match %vInterface, should be `%v(*gorm.DB) error`. Please see https://gorm.io/docs/hooks.html", schema, cbName, cbName) } diff --git a/vendor/gorm.io/gorm/statement.go b/vendor/gorm.io/gorm/statement.go index c6183724..ba5d3f18 100644 --- a/vendor/gorm.io/gorm/statement.go +++ b/vendor/gorm.io/gorm/statement.go @@ -341,7 +341,9 @@ func (stmt *Statement) BuildCondition(query interface{}, args ...interface{}) [] if where, ok := cs.Expression.(clause.Where); ok { if len(where.Exprs) == 1 { if orConds, ok := where.Exprs[0].(clause.OrConditions); ok { - where.Exprs[0] = clause.AndConditions(orConds) + if len(orConds.Exprs) == 1 { + where.Exprs[0] = clause.AndConditions(orConds) + } } } conds = append(conds, clause.And(where.Exprs...)) @@ -362,6 +364,9 @@ func (stmt *Statement) BuildCondition(query interface{}, args ...interface{}) [] for _, key := range keys { column := clause.Column{Name: key, Table: curTable} + if strings.Contains(key, ".") { + column = clause.Column{Name: key} + } conds = append(conds, clause.Eq{Column: column, Value: v[key]}) } case map[string]interface{}: @@ -374,6 +379,9 @@ func (stmt *Statement) BuildCondition(query interface{}, args ...interface{}) [] for _, key := range keys { reflectValue := reflect.Indirect(reflect.ValueOf(v[key])) column := clause.Column{Name: key, Table: curTable} + if strings.Contains(key, ".") { + column = clause.Column{Name: key} + } switch reflectValue.Kind() { case reflect.Slice, reflect.Array: if _, ok := v[key].(driver.Valuer); ok { diff --git a/vendor/modules.txt b/vendor/modules.txt index 95e5f35b..71b2f88c 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -364,7 +364,7 @@ gorm.io/driver/mysql # gorm.io/driver/sqlite v1.6.0 ## explicit; go 1.20 gorm.io/driver/sqlite -# gorm.io/gorm v1.30.0 +# gorm.io/gorm v1.30.1 ## explicit; go 1.18 gorm.io/gorm gorm.io/gorm/callbacks