File tree Expand file tree Collapse file tree 1 file changed +35
-0
lines changed Expand file tree Collapse file tree 1 file changed +35
-0
lines changed Original file line number Diff line number Diff line change @@ -69,3 +69,38 @@ func doNotCallTFailNowInsideGoroutine(m dsl.Matcher) {
69
69
Where (m ["t" ].Type .Implements ("testing.TB" ) && m ["fail" ].Text .Matches ("^(FailNow|Fatal|Fatalf)$" )).
70
70
Report ("Do not call functions that may call t.FailNow in a goroutine, as this can cause data races (see testing.go:834)" )
71
71
}
72
+
73
+ // InTx checks to ensure the database used inside the transaction closure is the transaction
74
+ // database, and not the original database that creates the tx.
75
+ func InTx (m dsl.Matcher ) {
76
+ m .Import ("github.com/coder/coder/coderd/database" )
77
+
78
+ m .Match (`
79
+ $x.InTx(func($y database.Store) error {
80
+ $*_
81
+ $*_ = $x.$f($*_)
82
+ $*_
83
+ })
84
+ ` ).Where (m ["x" ].Text != m ["y" ].Text && m ["x" ].Type .Implements ("database.Store" )).
85
+ At (m ["f" ]).
86
+ Report ("Do not use the database directly within the InTx closure. Use '$y' instead of '$x'." )
87
+
88
+ // When using a tx closure, ensure that if you pass the db to another
89
+ // function inside the closure, it is the tx.
90
+ // This will miss more complex cases such as passing the db as apart
91
+ // of another struct.
92
+ m .Match (`
93
+ $x.InTx(func($y database.Store) error {
94
+ $*_
95
+ $*_ = $f($*_, $x, $*_)
96
+ $*_
97
+ })
98
+ ` , `
99
+ $x.InTx(func($y database.Store) error {
100
+ $*_
101
+ $f($*_, $x, $*_)
102
+ $*_
103
+ })
104
+ ` ).Where (m ["x" ].Text != m ["y" ].Text && m ["x" ].Type .Implements ("database.Store" )).
105
+ At (m ["f" ]).Report ("Pass the tx database into the '$f' function inside the closure. Use '$y' over $x'" )
106
+ }
You can’t perform that action at this time.
0 commit comments