cares about is getters and setters. If you get those getters and
setters from an OR mapping engine, or something that just wraps SQL
queries:
(define-sql-row flight-cost (id cost))
(make-sql-getter *db-connection* flight-costs "SELECT id,cost FROM
flights WHERE cost < [[cost]] AND destination = [[destination]]")
-> #<procedure (? cost destination)>
Call that function on a cost and destination, and get back a list of
flight-cost records (define-sql-row is much like define-record, except
it makes a constructor that works from an SQL result)
(define-sql-row flight-details (id cost destination))
(make-sql-record-source *db-connection* flight-details "flights" ("id"))
...by introspecting into the structure of flight-details, produces a
function that does:
SELECT id,cost,destination FROM flights WHERE id = ?
...and which has a setter that, given an id and a flight-details-
record, does:
UPDATE flights SET id=?,cost=?,destination=? WHERE id = ?
By putting the abstraction layer above the level of "how the structure
of a result is specified", we can get away with doing all sorts of
different things.