Snooze uses a combinator-based query language that mirrors a large subset of standard SQL, including joins, nested queries, aggregate functions, limits and offsets.
The form is used to enter the query language, and is used to escape back into Scheme. Because statements are executed in the DBMS, the semantics of the query language are closer to SQL than Scheme.
Here is an example of a simple query:
|; (listof person)|
|; Find all people in the database:|
|( ( (select #:from person)))|
The block describes the query to perform. The select form creates a SELECT statement that selects all person records in the database. The procedure sends the query to the database, retrieves all the available query results, and turns them into a list.
Snooze automatically infers the type of query result. This example is selecting person records, so the results of the is a ( person).
The query language lets you customise the type of result in various ways. For example:
|; (listof string)|
|; Find the names of all people from the database.|
|( ( (select #:what person.name|
|; (listof (list string integer))|
|; Find the names and ages of all people from the database.|
|( ( (select #:what (person.name person.age)|
In the query language, dotted operators in identifiers are treated like operators meaning "attribute of". For example, person.name means "the name attribute of the person entity". The part before the dot has to be an entity or entity alias (see below).
supplies three query methods that retrieve data in different ways:
find-all retrieves a list of all matching results from the database.
find-one is like find-all but returns the first result found. If no results are found, returns #f instead.
(part ("(planet gen.ss (untyped unlib.plt 3 16))" "top"))
g:find is like find-all but returns a result generator.
Generators, defined in Unlib, are a lightweight iteration mechanism for traversing and modifying large datasets where menory consumption is a concern. Unlib provides useful combinators for manipulating generated data, including memory-efficient equivalents of fold, and .
Formally, blocks have the syntax below. The parts of the syntax are described in subsequent sections: