本文主要研究一下gorm的Locking
gorm.io/gorm@v1.20.11/clause/locking.go
type Locking struct { Strength string Table Table Options string } // Name where clause name func (locking Locking) Name() string { return "FOR" } // Build build where clause func (locking Locking) Build(builder Builder) { builder.WriteString(locking.Strength) if locking.Table.Name != "" { builder.WriteString(" OF ") builder.WriteQuoted(locking.Table) } if locking.Options != "" { builder.WriteByte(' ') builder.WriteString(locking.Options) } } // MergeClause merge order by clauses func (locking Locking) MergeClause(clause *Clause) { clause.Expression = locking }
Locking定义了Strength、Table、Options属性;Build方法先追加Strength,后面根据Table、Options属性追加语句
func TestLocking(t *testing.T) { results := []struct { Clauses []clause.Interface Result string Vars []interface{} }{ { []clause.Interface{clause.Select{}, clause.From{}, clause.Locking{Strength: "UPDATE"}}, "SELECT * FROM `users` FOR UPDATE", nil, }, { []clause.Interface{clause.Select{}, clause.From{}, clause.Locking{Strength: "SHARE", 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"}}, "SELECT * FROM `users` FOR UPDATE NOWAIT", nil, }, } for idx, result := range results { t.Run(fmt.Sprintf("case #%v", idx), func(t *testing.T) { checkBuildClauses(t, result.Clauses, result.Result, result.Vars) }) } }
Locking定义了Strength、Table、Options属性;Build方法先追加Strength,后面根据Table、Options属性追加语句;Strength支持SHARE、UPDATE;Options支持NOWAIT。