diff --git a/schema/field.go b/schema/field.go index 657e0a4b..c763da85 100644 --- a/schema/field.go +++ b/schema/field.go @@ -59,6 +59,7 @@ type Field struct { DataType DataType GORMDataType DataType PrimaryKey bool + PrimaryKeyPriority int AutoIncrement bool AutoIncrementIncrement int64 Creatable bool @@ -103,19 +104,20 @@ func (schema *Schema) ParseField(fieldStruct reflect.StructField) *Field { ) field := &Field{ - Name: fieldStruct.Name, - DBName: tagSetting["COLUMN"], - BindNames: []string{fieldStruct.Name}, - FieldType: fieldStruct.Type, - IndirectFieldType: fieldStruct.Type, - StructField: fieldStruct, - Tag: fieldStruct.Tag, - TagSettings: tagSetting, - Schema: schema, - Creatable: true, - Updatable: true, - Readable: true, - PrimaryKey: utils.CheckTruth(tagSetting["PRIMARYKEY"], tagSetting["PRIMARY_KEY"]), + Name: fieldStruct.Name, + DBName: tagSetting["COLUMN"], + BindNames: []string{fieldStruct.Name}, + FieldType: fieldStruct.Type, + IndirectFieldType: fieldStruct.Type, + StructField: fieldStruct, + Tag: fieldStruct.Tag, + TagSettings: tagSetting, + Schema: schema, + Creatable: true, + Updatable: true, + Readable: true, + PrimaryKey: utils.CheckTruth(tagSetting["PRIMARYKEY"], tagSetting["PRIMARY_KEY"], + tagSetting["PRIMARYKEY,PRIORITY"]), AutoIncrement: utils.CheckTruth(tagSetting["AUTOINCREMENT"]), HasDefaultValue: utils.CheckTruth(tagSetting["AUTOINCREMENT"]), NotNull: utils.CheckTruth(tagSetting["NOT NULL"], tagSetting["NOTNULL"]), @@ -124,6 +126,17 @@ func (schema *Schema) ParseField(fieldStruct reflect.StructField) *Field { AutoIncrementIncrement: DefaultAutoIncrementIncrement, } + if field.PrimaryKey { + field.PrimaryKeyPriority = 10 + } + + if field.TagSettings["PRIMARYKEY,PRIORITY"] != "" { + primaryKeyPriority, err := strconv.Atoi(tagSetting["PRIMARYKEY,PRIORITY"]) + if err == nil { + field.PrimaryKeyPriority = primaryKeyPriority + } + } + for field.IndirectFieldType.Kind() == reflect.Ptr { field.IndirectFieldType = field.IndirectFieldType.Elem() } diff --git a/schema/field_test.go b/schema/field_test.go index 300e375b..3fd5fda6 100644 --- a/schema/field_test.go +++ b/schema/field_test.go @@ -332,3 +332,37 @@ func TestTypeAliasField(t *testing.T) { checkSchemaField(t, alias, f, func(f *schema.Field) {}) } } + +type UserWithCompositePrimaryKey struct { + Foo uint `gorm:"primaryKey,priority:2;autoIncrement:false"` + Bar uint `gorm:"primaryKey,priority:1"` + Baz uint `gorm:"primaryKey"` +} + +func TestParseFieldWithCompositePrimaryKey(t *testing.T) { + user, err := schema.Parse(&UserWithCompositePrimaryKey{}, &sync.Map{}, schema.NamingStrategy{}) + if err != nil { + t.Fatalf("Failed to parse user with permission, got error %v", err) + } + + fields := []*schema.Field{ + { + Name: "Foo", DBName: "foo", BindNames: []string{"Foo"}, DataType: schema.Uint, PrimaryKey: true, + PrimaryKeyPriority: 2, Creatable: true, Updatable: true, Readable: true, Size: 64, + TagSettings: map[string]string{"AUTOINCREMENT": "false", "PRIMARYKEY,PRIORITY": "2"}, + }, + { + Name: "Bar", DBName: "bar", BindNames: []string{"Bar"}, DataType: schema.Uint, PrimaryKey: true, + PrimaryKeyPriority: 1, Creatable: true, Updatable: true, Readable: true, Size: 64, + TagSettings: map[string]string{"PRIMARYKEY,PRIORITY": "1"}, + }, + {Name: "Baz", DBName: "baz", BindNames: []string{"Baz"}, DataType: schema.Uint, PrimaryKey: true, + PrimaryKeyPriority: 10, Creatable: true, Updatable: true, Readable: true, Size: 64, + TagSettings: map[string]string{"PRIMARYKEY": "PRIMARYKEY"}, + }, + } + + for _, f := range fields { + checkSchemaField(t, user, f, func(f *schema.Field) {}) + } +}