7 Quick find procedures
(require (planet untyped/snooze/quick-find)) |
Quick find procedures provide convenient shorthands for retrieving persistent structs based on the values of their attributes. The procedures can be defined on a per-entity basis using the constructor macros custom-find-one, custom-find-all, custon-find-count and custom-g:find.
The constructor macros are described below and the quick find procedures themselves at the bottom of the page.
Defines a quick find wrapper for find-one. entity is the struct type identifier for an entity (e.g. student) and the order-clauses are as they appear in the syntax query language (see sql).
Like custom-find-one but defines a wrapper for find-all.
Like custom-find-one but defines a wrapper for g:find.
Like custom-find-one but defines a wrapper that finds the count of the matching structures in the database.
The quick-find procedures produced are keyword procedures that accept keywords with the same names as the attributes of the relevant entity. For example, the find-person procedure below:
(define-persistent-struct person |
([name type:string] |
[age type:integer] |
[programmer? type:boolean])) |
(define find-person |
(custom-find-one person #:order ((asc person.name)))) |
would accept keyword arguments for #:name, #:age and #:programmer?. These attribute arguments can be used in the following ways:
Passing a boolean, numeric, string, symbol, time-tai or time-utc literal matches structs with a specific attribute value.
Passing a list of literals matches structs with any corresponding attribute value.
Passing #f for any non-boolean attribute matches structs with null attributes.
Passing void matches any value at all (useful when wrapping quick-find calls in other procedures).
Arbitrary expressions may be specified by passing a procedure of type (attribute-alias -> expression).
Quick find procedures also accept #:what, #:order, #:limit and #:offset arguments:
the #:what argument accepts an entity, attribute, expression, or list of attributes or expression;
the #:order argument accepts a list of order terms;
the #:limit and #:offset arguments accept a natural number or #f.
Examples:
; SELECT * FROM person WHERE name = 'Dave'; |
(find-person #:name "Dave") |
; SELECT * FROM person WHERE name = 'Dave' AND age = 30; |
(find-person #:name "Dave" #:age 30) |
; SELECT * FROM person WHERE name IN ('Dave', 'Noel', 'Matt'); |
(find-person #:name (list "Dave" "Noel" "Matt")) |
; SELECT * FROM person WHERE name IS NULL AND "programmer?" = false; |
(find-person #:name #f #:programmer? #f) |
; SELECT * FROM person; |
(find-person #:name (void)) |
; SELECT * FROM person WHERE name ~ 'D.*'; |
(find-person #:name (lambda (attr) (sql:regexp-match attr "D.*"))) |
; SELECT surname FROM person; |
(find-person #:what (sql person.surname)) |
; SELECT * FROM person ORDER BY surname DESC; |
(find-person #:order (list (sql (desc person.surname)))) |