Repository: go-gorm/gorm
Pull request #6719 (2023-12-04 12:54:13)

Making locking parameters more intuitive
<!--
Make sure these boxes checked before submitting your pull request.

For significant changes, please open an issue to make an agreement on an implementation design/plan first before starting it.
-->

- [x] Do only one thing
- [x] Non breaking API changes
- [x] Tested

### What did this pull request do?
This PR provides constants for locking strength and locking option to make it easier to "guess". Partially solves https://github.com/go-gorm/gorm/issues/6720

### User Case Description

```
db.Clauses(clause.Locking{
  Strength: clause.LockingStrengthUpdate,
  Options: clause.LockingOptionsNoWait,
}).Find(&users)
```



Patch:
diff --git a/clause/locking.go b/clause/locking.go
index 290aac9..2bc48ce 100644
--- a/clause/locking.go
+++ b/clause/locking.go
@@ -1,5 +1,12 @@
 package clause
 
+const (
+	LockingStrengthUpdate    = "UPDATE"
+	LockingStrengthShare     = "SHARE"
+	LockingOptionsSkipLocked = "SKIP LOCKED"
+	LockingOptionsNoWait     = "NOWAIT"
+)
+
 type Locking struct {
 	Strength string
 	Table    Table


Test patch:
diff --git a/clause/locking_test.go b/clause/locking_test.go
index 0e60731..e45c8e7 100644
--- a/clause/locking_test.go
+++ b/clause/locking_test.go
@@ -14,17 +14,21 @@ func TestLocking(t *testing.T) {
 		Vars    []interface{}
 	}{
 		{
-			[]clause.Interface{clause.Select{}, clause.From{}, clause.Locking{Strength: "UPDATE"}},
+			[]clause.Interface{clause.Select{}, clause.From{}, clause.Locking{Strength: clause.LockingStrengthUpdate}},
 			"SELECT * FROM `users` FOR UPDATE", nil,
 		},
 		{
-			[]clause.Interface{clause.Select{}, clause.From{}, clause.Locking{Strength: "SHARE", Table: clause.Table{Name: clause.CurrentTable}}},
+			[]clause.Interface{clause.Select{}, clause.From{}, clause.Locking{Strength: clause.LockingStrengthShare, Table: clause.Table{Name: clause.CurrentTable}}},
 			"SELECT * FROM `users` FOR SHARE OF `users`", nil,
 		},
 		{
-			[]clause.Interface{clause.Select{}, clause.From{}, clause.Locking{Strength: "UPDATE"}, clause.Locking{Strength: "UPDATE", Options: "NOWAIT"}},
+			[]clause.Interface{clause.Select{}, clause.From{}, clause.Locking{Strength: clause.LockingStrengthUpdate, Options: clause.LockingOptionsNoWait}},
 			"SELECT * FROM `users` FOR UPDATE NOWAIT", nil,
 		},
+		{
+			[]clause.Interface{clause.Select{}, clause.From{}, clause.Locking{Strength: clause.LockingStrengthUpdate, Options: clause.LockingOptionsSkipLocked}},
+			"SELECT * FROM `users` FOR UPDATE SKIP LOCKED", nil,
+		},
 	}
 
 	for idx, result := range results {
diff --git a/schema/schema_helper_test.go b/schema/schema_helper_test.go
index 605aa03..bc32668 100644
--- a/schema/schema_helper_test.go
+++ b/schema/schema_helper_test.go
@@ -163,8 +163,8 @@ func checkSchemaRelation(t *testing.T, s *schema.Schema, relation Relation) {
 					t.Errorf("schema %v relation's join table tablename expects %v, but got %v", s, relation.JoinTable.Table, r.JoinTable.Table)
 				}
 
-				for _, f := range relation.JoinTable.Fields {
-					checkSchemaField(t, r.JoinTable, &f, nil)
+				for i := range relation.JoinTable.Fields {
+					checkSchemaField(t, r.JoinTable, &relation.JoinTable.Fields[i], nil)
 				}
 			}
 
diff --git a/schema/schema_test.go b/schema/schema_test.go
index 5bc0fb8..45e152e 100644
--- a/schema/schema_test.go
+++ b/schema/schema_test.go
@@ -46,8 +46,8 @@ func checkUserSchema(t *testing.T, user *schema.Schema) {
 		{Name: "Active", DBName: "active", BindNames: []string{"Active"}, DataType: schema.Bool},
 	}
 
-	for _, f := range fields {
-		checkSchemaField(t, user, &f, func(f *schema.Field) {
+	for i := range fields {
+		checkSchemaField(t, user, &fields[i], func(f *schema.Field) {
 			f.Creatable = true
 			f.Updatable = true
 			f.Readable = true
@@ -136,8 +136,8 @@ func TestParseSchemaWithAdvancedDataType(t *testing.T) {
 		{Name: "Admin", DBName: "admin", BindNames: []string{"Admin"}, DataType: schema.Bool},
 	}
 
-	for _, f := range fields {
-		checkSchemaField(t, user, &f, func(f *schema.Field) {
+	for i := range fields {
+		checkSchemaField(t, user, &fields[i], func(f *schema.Field) {
 			f.Creatable = true
 			f.Updatable = true
 			f.Readable = true