@@ -17,13 +17,54 @@ pub struct Select<'until_build, 'post_query> {
1717 pub ( crate ) resulting_columns : & ' until_build [ SelectColumnImpl < ' until_build > ] ,
1818 pub ( crate ) from_clause : & ' until_build str ,
1919 pub ( crate ) join_tables : & ' until_build [ JoinTableImpl < ' until_build , ' post_query > ] ,
20- pub ( crate ) where_clause : Option < & ' until_build Condition < ' post_query > > ,
20+ pub ( crate ) order_by_clause : & ' until_build [ OrderByEntry < ' until_build > ] ,
2121
2222 // Set by builder
23- pub ( crate ) order_by_clause : & ' until_build [ OrderByEntry < ' until_build > ] ,
23+ pub ( crate ) where_clause : Option < & ' until_build Condition < ' post_query > > ,
2424 pub ( crate ) distinct : bool ,
2525 pub ( crate ) limit : Option < u64 > ,
2626 pub ( crate ) offset : Option < u64 > ,
27+
28+ #[ cfg( feature = "postgres-only" ) ]
29+ pub ( crate ) locking_clause : Option < LockingClause > ,
30+ }
31+
32+ /// A `SELECT` statement's locking clause
33+ #[ cfg( feature = "postgres-only" ) ]
34+ #[ derive( Copy , Clone , Debug , Eq , PartialEq , Hash ) ]
35+ pub struct LockingClause {
36+ /// Strength of the row lock
37+ pub strength : LockStrength ,
38+
39+ /// How to acquire the row lock
40+ pub acquire : LockAcquire ,
41+ }
42+
43+ #[ cfg( feature = "postgres-only" ) ]
44+ /// Strength of a `SELECT` statement's row lock
45+ #[ derive( Copy , Clone , Debug , Eq , PartialEq , Hash ) ]
46+ pub enum LockStrength {
47+ /// `SELECT ... FOR UPDATE;`
48+ Update ,
49+ /// `SELECT ... FOR NO KEY UPDATE;`
50+ NoKeyUpdate ,
51+ /// `SELECT ... FOR SHARE;`
52+ Share ,
53+ /// `SELECT ... FOR KEY SHARE;`
54+ KeyShare ,
55+ }
56+
57+ #[ cfg( feature = "postgres-only" ) ]
58+ /// How to acquire a `SELECT` statement's row lock
59+ #[ derive( Default , Copy , Clone , Debug , Eq , PartialEq , Hash ) ]
60+ pub enum LockAcquire {
61+ /// `SELECT ... FOR <strength>;`
62+ #[ default]
63+ Wait ,
64+ /// `SELECT ... FOR <strength> NOWAIT;`
65+ NoWait ,
66+ /// `SELECT ... FOR <strength> SKIP LOCKED;`
67+ SkipLocked ,
2768}
2869
2970impl < ' until_build , ' post_build > Select < ' until_build , ' post_build > {
@@ -46,6 +87,13 @@ impl<'until_build, 'post_build> Select<'until_build, 'post_build> {
4687 self
4788 }
4889
90+ /// Set a lock on the resulting rows
91+ #[ cfg( feature = "postgres-only" ) ]
92+ pub fn locking_clause ( mut self , locking : LockingClause ) -> Self {
93+ self . locking_clause = Some ( locking) ;
94+ self
95+ }
96+
4997 /// Build the select query
5098 pub fn build ( self ) -> ( String , Vec < Value < ' post_build > > ) {
5199 let mut sql;
@@ -166,6 +214,26 @@ impl<'until_build, 'post_build> Select<'until_build, 'post_build> {
166214 }
167215 } ;
168216
217+ #[ cfg( feature = "postgres-only" ) ]
218+ if let Some ( locking) = self . locking_clause {
219+ write ! (
220+ sql,
221+ " FOR {}{}" ,
222+ match locking. strength {
223+ LockStrength :: Update => "UPDATE" ,
224+ LockStrength :: NoKeyUpdate => "NO KEY UPDATE" ,
225+ LockStrength :: Share => "SHARE" ,
226+ LockStrength :: KeyShare => "KEY SHARE" ,
227+ } ,
228+ match locking. acquire {
229+ LockAcquire :: Wait => "" ,
230+ LockAcquire :: NoWait => " NOWAIT" ,
231+ LockAcquire :: SkipLocked => " SKIP LOCKED" ,
232+ }
233+ )
234+ . unwrap ( ) ;
235+ }
236+
169237 write ! ( sql, ";" ) . unwrap ( ) ;
170238 }
171239 }
0 commit comments