mirror of
https://github.com/andwati/zitadel.git
synced 2026-10-18 05:52:51 +00:00
feat(database): add row locking options for queries (#10990)
Introduce options to lock rows returned by queries, allowing for more controlled transaction handling. This includes support for different lock modes such as "FOR UPDATE," "FOR NO KEY UPDATE," and "FOR SHARE." ## Additional information - closes https://github.com/zitadel/zitadel/issues/10930 - closes https://github.com/zitadel/zitadel/issues/10675
This commit is contained in:
@@ -73,6 +73,13 @@ func WithPermissionCheck(permission string) QueryOption {
|
||||
}
|
||||
}
|
||||
|
||||
// WithResultLock locks the results of the query during the transaction.
|
||||
func WithResultLock() QueryOption {
|
||||
return func(opts *QueryOpts) {
|
||||
opts.ShouldLock = true
|
||||
}
|
||||
}
|
||||
|
||||
type joinType string
|
||||
|
||||
const (
|
||||
@@ -119,6 +126,8 @@ type QueryOpts struct {
|
||||
// Permission required to read or write the resource.
|
||||
// When unset, no permission check is made.
|
||||
Permission string
|
||||
// ShouldLock the results during the transaction.
|
||||
ShouldLock bool
|
||||
}
|
||||
|
||||
// Matches implements [gomock.Matcher].
|
||||
@@ -184,6 +193,7 @@ func (opts *QueryOpts) Write(builder *StatementBuilder) {
|
||||
opts.WriteOrderBy(builder)
|
||||
opts.WriteLimit(builder)
|
||||
opts.WriteOffset(builder)
|
||||
opts.WriteLock(builder)
|
||||
}
|
||||
|
||||
func (opts *QueryOpts) WriteCondition(builder *StatementBuilder) {
|
||||
@@ -247,3 +257,10 @@ func (opts *QueryOpts) WriteLeftJoins(builder *StatementBuilder) {
|
||||
join.columns.Write(builder)
|
||||
}
|
||||
}
|
||||
|
||||
func (opts *QueryOpts) WriteLock(builder *StatementBuilder) {
|
||||
if !opts.ShouldLock {
|
||||
return
|
||||
}
|
||||
builder.WriteString(" FOR UPDATE")
|
||||
}
|
||||
|
||||
@@ -114,6 +114,16 @@ func TestQueryOptions(t *testing.T) {
|
||||
args: nil,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with lock",
|
||||
options: []QueryOption{
|
||||
WithResultLock(),
|
||||
},
|
||||
want: want{
|
||||
stmt: " FOR UPDATE",
|
||||
args: nil,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "multiple options",
|
||||
options: []QueryOption{
|
||||
@@ -122,9 +132,10 @@ func TestQueryOptions(t *testing.T) {
|
||||
WithOrderByDescending(NewColumn("table", "column")),
|
||||
WithLimit(10),
|
||||
WithOffset(5),
|
||||
WithResultLock(),
|
||||
},
|
||||
want: want{
|
||||
stmt: " LEFT JOIN other_table ON table.id = other_table.table_id WHERE table.column = $1 ORDER BY table.column DESC LIMIT $2 OFFSET $3",
|
||||
stmt: " LEFT JOIN other_table ON table.id = other_table.table_id WHERE table.column = $1 ORDER BY table.column DESC LIMIT $2 OFFSET $3 FOR UPDATE",
|
||||
args: []any{123, uint32(10), uint32(5)},
|
||||
},
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user