On this page:
4.1 Entities
entity
prop: entity
struct-has-entity?
struct-entity
4.2 Relationships
4.3 Attributes
attribute
entity-has-attribute?
entity-attribute
4.4 Attribute types
type
boolean-type
integer-type
real-type
string-type
symbol-type
time-utc-type
time-tai-type
4.5 Shorthand types
type: boolean
type: integer
type: real
type: string
type: symbol
type: time-utc
type: time-tai
4.6 Persistent structure utilities
struct-attributes
struct-has-attribute?
struct-attribute
set-struct-attribute!
set-struct-attributes!
make-persistent-struct/ defaults
copy-persistent-struct
update-persistent-struct-from-copy!
Version: 4.0.2.5

4 Entities, relationships and attributes

Snooze attaches ERA metadata to persistent struct types, providing information on how to serialize and deserialize structures and create aliases for use in queries:

4.1 Entities

(struct

 

entity

 (

name

 

 

 

 

table-name

 

 

 

 

struct-type

 

 

 

 

constructor

 

 

 

 

predicate

 

 

 

 

attributes

 

 

 

 

save-pipeline

 

 

 

 

insert-pipeline

 

 

 

 

update-pipeline

 

 

 

 

delete-pipeline))

  name : symbol?

  table-name : symbol?

  struct-type : struct-type?

  constructor : (any ... -> persistent-struct?)

  predicate : (any -> boolean?)

  attributes : (listof attribute?)

  save-pipeline : (listof procedure?)

  insert-pipeline : (listof procedure?)

  update-pipeline : (listof procedure?)

  delete-pipeline : (listof procedure?)

Metadata describing a particular struct-type. Pipeline procedures are of type:

  (connection? persistent-struct? -> persistent-struct?)

While the entity itself is useful to application programmers in a number of circumstances, most of the information inside the entity does not need to be accessed form application code. define-persistent-struct automatically binds an identifier of the form entity:foo to the entity for each persistent struct type:

  > (define-persistent-struct person

      ([name type:string]

       [age  type:integer]))

  > entity:person

  #<entity:person>

prop:entity : property?

A structure type property used to attach entity metadata to persistent structure types.

(struct-has-entity? struct)  boolean?

  struct : any

Returns #t if struct is a structure or structure type that has a value for prop:entity.

Examples:

  > (struct-has-entity? struct:person)

  #t

  > (struct-has-entity? (make-person "Dave" 30))

  #t

(struct-entity struct)  entity?

  struct : (U struct? struct-type?)

Returns the value of prop:entity that is associated with struct.

Examples:

  > (struct-entity struct:person)

  #<entity:person>

  > (struct-entity (make-person "Dave" 30))

  #<entity:person>

4.2 Relationships

Snooze does not currently have explicit support for relationships. These are planned for a future release. For now, the recommended way of creating a relationship between two structures is by using a foreign key field of type:integer:

  (define-persistent-struct person

    ([name type:string]))

  (define-persistent-struct pet

    ([name     type:string]

     [owner-id type:integer]))

A caveat to this approach is that you have to make sure the target structure is saved before you reference its ID for the foreign key:

  ; This is incorrect.

  ; The person will not have an ID because it has not been saved:

  (make-pet "Garfield" (person-id (make-person "Jon")))

  ; This is correct.

  ; The call to save! allocates an ID for the person:

  (make-pet "Garfield" (person-id (save! (make-person "Jon"))))

4.3 Attributes

(struct

 

attribute

 (

name

 

 

 

 

column-name

 

 

 

 

entity

 

 

 

 

index

 

 

 

 

accessor

 

 

 

 

mutator

 

 

 

 

type))

  name : symbol?

  column-name : symbol?

  entity : entity?

  index : natural?

  accessor : (persistent-struct? -> any)

  mutator : (persistent-struct? any -> void?)

  type : type?

Metadata describing a particular attribute (or field or column) of an entity.

define-persistent-struct automatically binds an identifier of the form attr:foo-bar for each attribute of each persistent struct type:

  > attr:person-id

  #<attr:person-id>

  > attr:person-revision

  #<attr:person-revision>

  > attr:person-name

  #<attr:person-name>

  > attr:person-age

  #<attr:person-age>

(entity-has-attribute? entity attribute)  boolean?

  entity : entity?

  attribute : (U attribute? symbol?)

Returns #t if entity has the supplied attribute, #f otherwise. attribute can be an attribute structure or an attribute name.

Examples:

  > (entity-has-attribute? entity:person attr:person-name)

  #t

  > (entity-has-attribute? entity:person 'name)

  #t

(entity-attribute entity name)  attribute?

  entity : entity?

  name : (U attribute? symbol?)

Determines if entity has the supplied attribute. Returns the attribute exists; raises exn:fail otherwise.

Examples:

  > (entity-attribute entity:person attr:person-name)

  #<attr:person-name>

  > (entity-attribute entity:person 'name)

  #<attr:person-name>

  > (entity-attribute entity:person 'nom)

  Attribute not found: #<entity:person> nom

4.4 Attribute types

Each attribute has an associated type that determines the type of column used in the database. Types come in several flavours, described below. Note that the reflection of a type may be different in different DBMS types. For example, SQLite does not support the SQL TIMESTAMP data type, so Snooze uses integers to serialize time values.

(struct

 

type

 

(allows-null? default))

  allows-null? : boolean?

  default : any

(struct

 

(boolean-type type)

 

())

Stores #t and #f values. There is no direct Scheme representation of NULL; NULL values in the database are mapped to #f in Scheme.

(struct

 

(integer-type type)

 

())

Stores integer values. NULL values in the database are mapped to #f in Scheme.

(struct

 

(real-type type)

 

())

Stores real number values. NULL values in the database are mapped to #f in Scheme.

(struct

 

(string-type type)

 

(max-length))

  max-length : integer?

Stores string values as VARCHARs or arbitrary length TEXTs. The value of max-length determines the SQL type. NULL values in the database are mapped to #f in Scheme.

(struct

 

(symbol-type type)

 

(max-length))

  max-length : integer?

Like string-type but for symbol values.

(struct

 

(time-utc-type type)

 

(max-length))

  max-length : integer?

Stores SRFI 19 UTC times as GMT TIMESTAMP WITHOUT TIME ZONEs (or INTEGERs in SQLite). NULL values in the database are mapped to #f in Scheme.

(struct

 

(time-tai-type type)

 

(max-length))

  max-length : integer?

Like time-utc-type but for SRFI 19 TAI times.

4.5 Shorthand types

Snooze provides a number of short-hand types. The types below all allow and default to NULL, and type:string and type:symbol allow data of arbitrary length:

type:boolean : type?

type:integer : type?

type:real : type?

type:string : type?

type:symbol : type?

type:time-utc : type?

type:time-tai : type?

4.6 Persistent structure utilities

(struct-attributes struct)  list?

  struct : persistent-struct?

Returns a list of the values of the attributes of struct (including its ID and revision).

Examples:

  > (define-persistent-struct person

      ([name type:string] [age type:integer]))

  > (define dave (make-person "Dave" 30))

  > (struct-attributes dave)

  (#f #f "Dave" 30)

(struct-has-attribute? struct name)  boolean?

  struct : persistent-struct?

  name : (U attribute? symbol?)

Returns #t if struct has an attribute with the supplied name, #f otherwise.

Examples:

  > (struct-has-attribute? dave attr:person-name)

  #t

  > (struct-has-attribute? dave 'age)

  #t

  > (struct-has-attribute? dave 'nom)

  #f

(struct-attribute struct name)  any

  struct : persistent-struct?

  name : (U attribute? symbol?)

Returns the value from struct of the attribute with the supplied name. Raises exn:fail:contract if struct does not have a corresponding attribute.

Examples:

  > (struct-attribute dave attr:person-name)

  "Dave"

  > (struct-attribute dave 'age)

  30

  > (struct-attribute dave 'nom)

  Attribute not found: #<entity:person> nom

(set-struct-attribute! struct name value)  void?

  struct : persistent-struct?

  name : (U attribute? symbol?)

  value : any

Mutates struct, setting the value of the attribute with the supplied name.

Examples:

  > (set-struct-attribute! dave attr:person-name "Noel")

  > (set-struct-attribute! dave 'age #f)

  > (struct-attributes dave)

  (#f #f "Noel" #f)

(set-struct-attributes! struct vals)  void?

  struct : persistent-struct?

  vals : list?

Mutates struct, setting the values of all its attributes. vals must contain an ID, a revision, and one value for each attribute of struct in the order specified inthe define-persistent-struct form.

Examples:

  > (set-struct-attributes! dave (list #f #f "Dave" 30))

  > (struct-attributes dave)

  (#f #f "Dave" 30)

(make-persistent-struct/defaults

 

entity

 

 

 

attr

 

 

 

value

 

 

 

attr2

 

 

 

value2 ...)

 

  persistent-struct?

  entity : entity?

  attr : (U attribute? symbol?)

  value : any

  attr2 : (U attribute? symbol?)

  value2 : any

Returns a new persistent of the supplied type, with default values for all attributes except those specified in the arguments. Used in the implementation of the keyword constructor created by define-persistent-struct.

Each attr must be followed by a corresponding value.

Examples:

  > (make-persistent-struct/defaults

     entity:person attr:person-name "Noel")

  #(struct:person #f #f "Noel" #f)

(copy-persistent-struct

 

struct

 

 

 

 

 

 

attr

 

 

 

 

 

 

value

 

 

 

 

 

 

attr2

 

 

 

 

 

 

value2 ...)

 

 

persistent-struct?

  struct : persistent-struct?

  attr : (U attribute? symbol?)

  value : any

  attr2 : (U attribute? symbol?)

  value2 : any

Returns a new persistent structure with the same type and attributes of struct, except where new values are supplied in the arguments. Used in the implentation of the copy procedure created by define-persistent-struct.

Each attr must be followed by a corresponding value.

(update-persistent-struct-from-copy!

 

struct

 

 

 

copy)

 

  persistent-struct?

  struct : persistent-struct?

  copy : persistent-struct?

Mutates struct to be the same as copy. Used when rolling back cancelled transactions.

Examples:

  > (copy-persistent-struct dave attr:person-name "Noel")

  #(struct:person #f #f "Noel" 30)