A persistent structure is a PLT structure that Snooze can save to a database. Snooze attaches entity metadata to each persistent struct type via a property called . The metadata serves two purposes:
it tells Snooze how to serialize and deserialize structs of that type;
it indirectly allows the programmer to refer to the entity in queries.
A persistent structure type with n fields is mapped to a database table with n+2 columns: an integer id which acts as a primary key for table, an integer revision number which helps prevent against concurrent writes in multi-threaded applications, and a column for each attribute in the type definition. ids and revisions are automatically allocated by Snooze and should not normally be updated by application code: the lifecycle of these fields is described in Saving and deleting structures.
Creates a new persistent structure, and binds variables related to the new structure type. A with n attributes defines the following identifiers:
entity:id, an entity metadata value that can be used in queries and with other Snooze procedures;
attr:id-attr-id, a set of attribute metadata values that can be used in queries and with other Snooze procedures;
struct:id, the usual structure type descriptor defined by define-struct;
make-id, a constructor procedure that takes n arguments and returns a new struct;
make-id/defaults, a keyword constructor that takes up to n+2 keyword arguments and returns a new struct. The keywords accepted include #:id, #:revision and the various attr-ids: where a keyword is omitted, the default value of the attribute is used;
copy-id, a copy constructor that takes a persistent structure and up to n+2 keyword arguments and returns a new struct. The keywords accepted include #:id, #:revision and the various attr-ids: where a keyword is omitted, the value of the attribute in the existing structure is used;
id?, a predicate that returns #t for instances of the structure type and #f for any other value;
id-attr-id, a set of accessor procedures, including id-id and id-revision, that take a persistent structure as an argument and return the value of the corresponding attribute;
set-id-attr-id!, a set of mutator procedures, including set-id-id! and set-id-revision!, that take a persistent structure and an arbitrary Scheme value as arguments, and mutate the structure to set the corresponding attribute to the supplied value;
By default, persistent structures are stored in rows in a database table of the same name. The #:table-name entity option allows you to override the default table name and provide something more user-friendly: hyphen characters in table names must be escaped in most DBMSs. Similarly, the #:column-name attribute option allows you to override the default column name for each attribute. The column names for id and revision may not be changed.
The #:on-save, #:on-insert, #:on-update and #:on-delete keywords allow you to specify database pipelines to be run during calls to and .
Persistent structures are completely inspectable. ids and revisions are visible in their printed forms and are exposed by the struct form from scheme/match. For example:
; person : (persistent-struct (U string #f) (U integer #f))
; dave : person
; Print dave: id and revision shown:
#(struct:person #f #f "Dave" 30)
; Match against dave: no id and revision:
(#f #f "Dave" 30)
Persistent structure types are not meant to be subtyped, although this feature is planned for a future version of Snooze.
Every persistent struct has an ID and a revision. The ID acts as a primary key in the database, and the revision helps protect against concurrent database updates.
( struct) → (U integer? #f)
Returns the ID of struct, or #f if struct is not saved in the database.
( struct id) → void?
id : (U integer? #f)
Sets the id of struct. You should not normally have to use this procedure: Snooze does this automatically when you save or delete a struct.
( struct) → (U integer? #f)
Returns the last revision number of struct, or #f if struct is not saved in the database.
The revision number is set to 0 when a structure is first saved and is incremented on each subsequent save. Snooze raises if a structure has an incompatible revision number when you try to save it. This protects against common concurrency problems.
( struct rev) → void?
rev : (U integer? #f)
Sets the revision number of struct to rev. You should not normally have to use this procedure: Snooze does this automatically when you save or delete a struct.