Skip to content

Commit fecbcf2

Browse files
committed
query: add select-for-update
1 parent a0ff47c commit fecbcf2

7 files changed

Lines changed: 58 additions & 16 deletions

File tree

deta-doc/deta.scrbl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -980,6 +980,12 @@ queries.
980980
schema.
981981
}
982982

983+
@defproc[(select-for-update [q query?]) query?]{
984+
Modifies @racket[q] to lock its rows against concurrent updates.
985+
986+
@history[#:added "0.20"]
987+
}
988+
983989
@defform[
984990
(union query-1 query-2)
985991
]{

deta-lib/info.rkt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#lang info
22

33
(define license 'BSD-3-Clause)
4-
(define version "0.19")
4+
(define version "0.20")
55
(define collection "deta")
66

77
(define deps '("base"

deta-lib/private/ast.rkt

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,8 @@
100100
(struct-out union)
101101
(struct-out order-by)
102102
(struct-out returning)
103-
(struct-out where))
103+
(struct-out where)
104+
(struct-out select-for))
104105

105106
(struct clause ()
106107
#:transparent)
@@ -139,6 +140,9 @@
139140
(struct where clause (e)
140141
#:transparent)
141142

143+
(struct select-for clause (what)
144+
#:transparent)
145+
142146

143147
;; statements ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
144148

@@ -186,7 +190,7 @@
186190
#:returning [returning #f])
187191
(update table assignments where returning))
188192

189-
(struct select stmt (distinct? columns from where group-by union order-by offset limit)
193+
(struct select stmt (distinct? columns from where group-by union order-by limit offset for-spec)
190194
#:transparent)
191195

192196
(define (make-select #:distinct? [distinct? #f]
@@ -196,6 +200,7 @@
196200
#:group-by [group-by #f]
197201
#:union [union #f]
198202
#:order-by [order-by #f]
203+
#:limit [limit #f]
199204
#:offset [offset #f]
200-
#:limit [limit #f])
201-
(select distinct? columns from where group-by union order-by offset limit))
205+
#:for [for-spec #f])
206+
(select distinct? columns from where group-by union order-by limit offset for-spec))

deta-lib/private/dialect/standard.rkt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@
237237
[(list exprs ...)
238238
(write/sep exprs write-expr)]
239239

240-
[(select distinct? columns from where group-by union order-by offset limit)
240+
[(select distinct? columns from where group-by union order-by limit offset for-spec)
241241
(write-string "SELECT ")
242242
(when distinct?
243243
(write-string "DISTINCT ")
@@ -255,7 +255,11 @@
255255
(when union (display/space union))
256256
(when order-by (display/space order-by))
257257
(when limit (display/space limit))
258-
(when offset (display/space offset))]
258+
(when offset (display/space offset))
259+
(when for-spec (display/space for-spec))]
260+
261+
[(select-for 'update)
262+
(write-string "FOR UPDATE")]
259263

260264
[(update table assignments where returning)
261265
(write-string "UPDATE ")

deta-lib/private/query.rkt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@
109109
string?
110110
(hash/c symbol? ast:expr?)
111111
query?)]
112+
[select-for-update
113+
(-> query? query?)]
112114
[subquery (-> select-query? ast:subquery?)]
113115
[union (-> select-query? select-query? query?)]
114116
[update (-> select-query? assignment/c assignment/c ... query?)]
@@ -191,6 +193,18 @@
191193
(ast:qualified tbl-alias (field-name fld)))))))
192194
(project-onto q* s))
193195

196+
(define (select-for-update q)
197+
(match q
198+
[(query schema opts (? ast:select? stmt))
199+
(query schema opts (struct-copy
200+
ast:select stmt
201+
[for-spec (ast:select-for 'update)]))]
202+
203+
[_
204+
(raise-argument-error
205+
'select-for-update
206+
"a SELECT query" q)]))
207+
194208
(define (limit q n)
195209
(match q
196210
[(query schema opts stmt)

deta-lib/query.rkt

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -233,14 +233,18 @@
233233

234234
(provide
235235
(contract-out
236-
[in-entities (->* [connection? dyn:query?]
237-
[#:batch-size (or/c exact-positive-integer? +inf.0)]
238-
sequence?)]
239-
[query-entities (->* [connection? dyn:query?]
240-
[#:batch-size (or/c exact-positive-integer? +inf.0)]
241-
(listof entity?))]
242-
[lookup (-> connection? dyn:query? any)]
243-
[refresh (-> connection? entity? (or/c #f entity?))])
236+
[in-entities
237+
(->* [connection? dyn:query?]
238+
[#:batch-size (or/c exact-positive-integer? +inf.0)]
239+
sequence?)]
240+
[query-entities
241+
(->* [connection? dyn:query?]
242+
[#:batch-size (or/c exact-positive-integer? +inf.0)]
243+
(listof entity?))]
244+
[lookup
245+
(-> connection? dyn:query? any)]
246+
[refresh
247+
(-> connection? entity? (or/c #f entity?))])
244248

245249
from
246250
group-by
@@ -260,7 +264,8 @@
260264
[dyn:delete delete]
261265
[dyn:union union]
262266
[dyn:project-onto project-onto]
263-
[dyn:project-virtual-fields project-virtual-fields])
267+
[dyn:project-virtual-fields project-virtual-fields]
268+
[dyn:select-for-update select-for-update])
264269

265270
(contract-out
266271
[make-entity

deta-test/deta/sql-postgresql.rkt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,14 @@
276276

277277
"SELECT CASE WHEN (MIN(d.employees)) > 0 THEN AVG(d.expenses / d.employees) ELSE 0 END FROM departments AS d"))
278278

279+
(test-case "FOR UPDATE"
280+
(check-emitted
281+
(select-for-update
282+
(where
283+
(from "workspaces" #:as w)
284+
(= w.id 1)))
285+
"SELECT * FROM workspaces AS w WHERE w.id = 1 FOR UPDATE"))
286+
279287
(test-suite
280288
"from"
281289

0 commit comments

Comments
 (0)