The oook Reference Manual

Table of Contents

Next: , Previous: , Up: (dir)   [Contents][Index]

The oook Reference Manual

This is the oook Reference Manual, version 0.2.0, generated automatically by Declt version 2.3 "Robert April" on Tue Feb 20 09:08:10 2018 GMT+0.


Next: , Previous: , Up: Top   [Contents][Index]

1 Introduction

OOOK!

Quicklisp License: MIT

OOOK is some data manipulation magic on top of the venerable CL-SQL package, which has been providing a solid SQL abstraction in Common Lisp for years.

The goal of OOOK is to greatly decrease "standard" database-driven web application development time with the trade-off of slightly less flexiblity. With that in mind, some of the features include:

Note: Database design should be driven by the data, not by the code that uses it! To encourage this, OOOK will never have functionality to manipulate the database schema.

Also, OOOK is still under development and the API is changing fairly frequently. It is regularly used in its present state, however, and is mostly stable.

Overview

Create models of tables in the database with defmodel:

(oook:defmodel post (:belongs-to user)
  "Some interesting prose, full of wisdom"
  (date_published :type clsql:wall-time)
  (title :column "post-title")
  content)

(oook:defmodel user (:has-many posts)
  "Someone who writes posts"
  name
  (level :type integer :documentation "Skill level"))

This creates two CLOS classes which model the "post" and "user" database tables, including the relationship between the two. The models have brief dostrings, custom slots (including types) and associations with other models.

Note: the defmodel macro creates two CLSQL view-classes, using clsql:def-view-class, containing the specified slots and a number of additional slots for managing the joins.

Example Workflow:

Create a new user using the standard CLOS make-instance:

(defvar wizzard
  (make-instance 'user :name "Rincewind" :level 0))

Create a new post and add it to the user:

(push (posts wizzard) (make-instance 'post :title "On Staying Alive")))

Save the new user (and post) in the database:

(oook:save wizzard)  ; Will save both the user and his post

Find something, either by ID with the built-in find-by-id helper, or construct a CLSQL statement for more complex queries (OOOK provides a few other helpers, see the documentation).

(oook:find-by-id 'post 2)  ; Find the post row with ID == 2
(clsql:select 'user)  ; Select all users

POST/JSON serialisation

OOOK makes it simple to build a model instance given a set of POST data, as long as the POST data is constructed according to a few rules. If you use the HTML generation helpers below, this is handled automatically!

More documentation coming soon... But have a look at serialise.lisp!

HTML Generation

OOOK provides some utilties for viewing and editing model data. In the simplest form, you can generate an HTML form to modify a model with a few lines:

(let ((the-post (make-instance 'post :title "New Post")))
  (oook:get-edit-form the-post "/save"))

With the previous definition of post, this returns the following HTML.

<form class="ui form" action=/save method=POST>
 <div class=field>
  <label>Content</label>
  <input type=text name=post[content]> 
 </div>
 <div class=field>
  <label>Title</label>
  <input type=text name=post[title] value="New Post"> 
 </div>
 <div class=field>
  <label>Date_Published</label>
  <input type=date name=post[date_published]> 
 </div>
 <div class=field>
  <label>User Id</label>
  <input type=number name=post[user_id]> 
 </div>
 <button class="ui primary button" type=submit>Save</button> 
</form>

Things to note

Custom Built Forms

OOOK provides a context manager, with-record-type to make it easier to build custom forms.

Documentation coming soon... But have a look at html.lisp!

Utilities

Enhanced printing

Use oook:def-enhanced-printer to quickly enhance the printed representations of models.

CL-USER> (oook:def-enhanced-printer post :slot 'title)
...
CL-USER> (format t (oook:find-by-id 'post 5))
#<POST "The Joys of Boredom">

Models Implementation Notes

Overview

Like another well known library, all tables are expected to have at least these three columns:

These have historically been found to be useful in typical web applications. The id field is always required, and will be an index into the table. The second two can be disabled by passing :timestamped nil to defmodel.

In addition, models you define will typically have a number of other fields, corresponding to columns in the table, and possibly a number of associated models.

Associated models

A model can be associated to other models in a number of ways.

Models are selected exactly as you would with CL-SQL, and, by default, the joins are lazily loaded (i.e. a "join" slot is only populated from the DB when it is accessed).

The fun part is saving.

oook:save will save any associated models that belong to the instance it is called with. New rows will be created as necessary.

has-one (FK in Left)

Left requires one instance of Right, but Right doesn't care or know about this relationship. (e.g. ingredient -> unit).

owns-one (FK in right) - use with belongs-to (blargh redundancy)

Left owns one Right, and Right knows it. Left cannot have more than one Right. (e.g. user <- config)

belongs-to (FK in Left) - use with owns-many or owns-one

Left is owned by one Right. Left cannot have more than one owner. (e.g. config <- user). However Right might have more than one Left (e.g. step* <- recipe)

owns-many (FK in Right) - use with belongs-to

Left has many Rights, and the Rights know which Left they belong to. (e.g. recipe <- step*)

many-to-many (intersection table)

Not implemented yet

Left references many instances of Right, and Right might be referenced by many instances of Left. (e.g. programmer <-> project, a programmer is part of many projects and a project has many programmers)

Get: do not try to resolve the parent relation (circular dep)

LICENSE

MIT License

Copyright (c) 2017 Ricardo M. H. da Silva

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


Next: , Previous: , Up: Top   [Contents][Index]

2 Systems

The main system appears first, followed by any subsystem dependency.


Previous: , Up: Systems   [Contents][Index]

2.1 oook

Author

Ric da Silva <ric@rmhsilva.com>

License

MIT

Description

Some magic on the shoulders of CLSQL

Version

0.2.0

Dependencies
Source

oook.asd (file)

Component

src (module)


Next: , Previous: , Up: Top   [Contents][Index]

3 Modules

Modules are listed depth-first from the system components tree.


Previous: , Up: Modules   [Contents][Index]

3.1 oook/src

Parent

oook (system)

Location

src/

Components

Next: , Previous: , Up: Top   [Contents][Index]

4 Files

Files are sorted by type and then listed depth-first from the systems components trees.


Previous: , Up: Files   [Contents][Index]

4.1 Lisp


Next: , Previous: , Up: Lisp files   [Contents][Index]

4.1.1 oook.asd

Location

oook.asd

Systems

oook (system)


Next: , Previous: , Up: Lisp files   [Contents][Index]

4.1.2 oook/src/package.lisp

Parent

src (module)

Location

src/package.lisp

Packages

Next: , Previous: , Up: Lisp files   [Contents][Index]

4.1.3 oook/src/utils.lisp

Parent

src (module)

Location

src/utils.lisp

Exported Definitions
Internal Definitions

Next: , Previous: , Up: Lisp files   [Contents][Index]

4.1.4 oook/src/serialise.lisp

Parent

src (module)

Location

src/serialise.lisp

Exported Definitions
Internal Definitions

get-slot-type (function)


Next: , Previous: , Up: Lisp files   [Contents][Index]

4.1.5 oook/src/html.lisp

Parent

src (module)

Location

src/html.lisp

Exported Definitions
Internal Definitions

Next: , Previous: , Up: Lisp files   [Contents][Index]

4.1.6 oook/src/methods.lisp

Parent

src (module)

Location

src/methods.lisp

Exported Definitions
Internal Definitions

Previous: , Up: Lisp files   [Contents][Index]

4.1.7 oook/src/macro.lisp

Parent

src (module)

Location

src/macro.lisp

Exported Definitions
Internal Definitions

Next: , Previous: , Up: Top   [Contents][Index]

5 Packages

Packages are listed by definition order.


Next: , Previous: , Up: Packages   [Contents][Index]

5.1 oook

Source

package.lisp (file)

Use List

common-lisp


Next: , Previous: , Up: Packages   [Contents][Index]

5.2 oook.methods

Source

package.lisp (file)

Use List

common-lisp

Exported Definitions
Internal Definitions

Next: , Previous: , Up: Packages   [Contents][Index]

5.3 oook.serialise

A set of serialisation utilities, including to/from alists, to json (using jonathan)

Source

package.lisp (file)

Use List

common-lisp

Exported Definitions
Internal Definitions

Next: , Previous: , Up: Packages   [Contents][Index]

5.4 oook.macro

Defines the ‘defmodel’ macro, and the associated functions

Source

package.lisp (file)

Nickname

macro

Use List

common-lisp

Exported Definitions
Internal Definitions

Previous: , Up: Packages   [Contents][Index]

5.5 oook.utils

Source

package.lisp (file)

Use List

common-lisp

Exported Definitions
Internal Definitions

Next: , Previous: , Up: Top   [Contents][Index]

6 Definitions

Definitions are sorted by export status, category, package, and then by lexicographic order.


Next: , Previous: , Up: Definitions   [Contents][Index]

6.1 Exported definitions


Next: , Previous: , Up: Exported definitions   [Contents][Index]

6.1.1 Special variables

Special Variable: *default-slot-type*
Package

oook.macro

Source

macro.lisp (file)

Special Variable: *serialisation-options*

Options that control how objects are serialised

Package

oook.serialise

Source

serialise.lisp (file)


Next: , Previous: , Up: Exported definitions   [Contents][Index]

6.1.2 Macros

Macro: def-enhanced-printer TYPE &key SLOT

Enhances ‘print-object’ for ‘type’, adding the ‘slot’ attribute to it

Package

oook.utils

Source

utils.lisp (file)

Macro: defmodel MODEL-NAME (&key TABLE TIMESTAMPED HAS-ONE OWNS-ONE OWNS-MANY BELONGS-TO) &body FIELDS

Define a class that models DB structure

Package

oook.macro

Source

macro.lisp (file)

Macro: with-record-type (CLASS) &body BODY
Package

oook.serialise

Source

html.lisp (file)

Macro: with-serialisation-options (&rest OPTIONS) &body BODY

Execute ‘body’ with json options set to ‘options’

Package

oook.serialise

Source

serialise.lisp (file)


Next: , Previous: , Up: Exported definitions   [Contents][Index]

6.1.3 Functions

Function: destroy INST

Delete ‘inst’ and associated models

Package

oook.methods

Source

methods.lisp (file)

Function: filter ()
Package

oook.methods

Source

methods.lisp (file)

Function: find-by-id TYPE ID

Find a model with ‘id’

Package

oook.methods

Source

methods.lisp (file)

Function: from-alist CLASS ALIST &key INCLUDE-JOINS

Create an instance of ‘class’, given ‘alist’ containing mapping of slots to values, in caveman2 parsed params format.

Package

oook.serialise

Source

serialise.lisp (file)

Function: gen-html-table RECORDS &key EXCLUDE-SLOTS TABLE-CLASSES

Print an HTML table listing the data in ‘records’

Package

oook.serialise

Source

html.lisp (file)

Function: get-edit-form RECORD ACTION &key EXCLUDE-SLOTS
Package

oook.serialise

Source

html.lisp (file)

Function: parse-as-type VALUE TYPE

Try to parse ‘type’ from input ‘value’

Package

oook.utils

Source

utils.lisp (file)

Function: pprint-model INST &key STREAM SLOTS INCLUDE-JOINS

Pretty print ‘inst’

Package

oook.serialise

Source

serialise.lisp (file)

Function: save INST

Save ‘inst’ and associated models

Package

oook.methods

Source

methods.lisp (file)

Function: search-like MODEL COLUMN &key LIKE SINGLEP FMT

Search the DB for ‘model’ using LIKE to match column. If ‘singlep’ is t, only one result is returned

Package

oook.utils

Source

utils.lisp (file)

Function: sql-field SYMBOL

Make ‘symbol’ suitable for SQL name

Package

oook.utils

Source

utils.lisp (file)

Function: to-alist INST &key INCLUDE-JOINS

Return an a-list representation of ‘inst’

Package

oook.serialise

Source

serialise.lisp (file)


Previous: , Up: Exported definitions   [Contents][Index]

6.1.4 Generic functions

Generic Function: created-at INST
Package

oook.macro

Source

macro.lisp (file)

Generic Function: foreign-key INST
Package

oook.macro

Source

macro.lisp (file)

Generic Function: id INST

Read the ‘id’ attribute

Package

oook.macro

Source

macro.lisp (file)

Generic Function: join-fks INST

Return the foreign keys for models in has-one and belongs-to

Package

oook.macro

Source

macro.lisp (file)

Generic Function: last-modified INST
Package

oook.macro

Source

macro.lisp (file)

Generic Function: owns-many INST
Package

oook.macro

Source

macro.lisp (file)

Generic Function: owns-one INST
Package

oook.macro

Source

macro.lisp (file)

Generic Function: serialisable-fields INST

Return the slots in ‘inst’ that will be included when ‘to-alist’ is called

Package

oook.macro

Source

macro.lisp (file)

Generic Function: serialisable-joins INST
Package

oook.macro

Source

macro.lisp (file)


Previous: , Up: Definitions   [Contents][Index]

6.2 Internal definitions


Next: , Previous: , Up: Internal definitions   [Contents][Index]

6.2.1 Macros

Macro: do-each-owns-many (INST RIGHT VALUE) &body BODY

For each model in the owns-many relation of ‘inst’, execute ‘body’ with the symbol ‘right’ bound to the model type, and the symbol ‘value’ bound to the current slot-value of the relation

Package

oook.methods

Source

methods.lisp (file)

Macro: ensure-slot-type INST SLOT TYPE

Create form to ensure that ‘slot’ in ‘inst’ is of type ‘type’

Package

oook.utils

Source

utils.lisp (file)


Previous: , Up: Internal definitions   [Contents][Index]

6.2.2 Functions

Function: all-same-type-p RECORDS

Check everything in ‘records’ is the same type

Package

oook.serialise

Source

html.lisp (file)

Function: ensure-integer THING

Return ‘thing’ as an integer

Package

oook.utils

Source

utils.lisp (file)

Function: field-for-normal-slot CLASS SLOT &optional VALUE
Package

oook.serialise

Source

html.lisp (file)

Function: field-label-for SLOT
Package

oook.serialise

Source

html.lisp (file)

Function: field-name-for CONTAINER-NAME SLOT
Package

oook.serialise

Source

html.lisp (file)

Function: get-slot-type CLASS SLOT

Get the type of ‘slot’ in ‘class’

Package

oook.serialise

Source

serialise.lisp (file)

Function: make-clsql-base-slot SLOT

Create a clsql base slot form from ‘slot’

Package

oook.macro

Source

macro.lisp (file)

Function: make-clsql-join-slot NAME &key MODEL HOME FOREIGN SET
Package

oook.macro

Source

macro.lisp (file)

Function: make-clsql-key-slot NAME

Create a clsql foreign key slot form from ‘slot’

Package

oook.macro

Source

macro.lisp (file)

Function: make-foreign-key SYMBOL

Create a foreign key (append _id) for symbol

Package

oook.macro

Source

macro.lisp (file)

Function: new-row-p INST

Return T if ‘inst’ does not have a row in the DB

Package

oook.methods

Source

methods.lisp (file)

Function: slot-type-without-null CLASS SLOT

If a slot type is something like (OR NULL BOOLEAN), return just BOOLEAN

Package

oook.serialise

Source

html.lisp (file)

Function: sql-field-keyword SYMBOL

Make ‘symbol’ suitable for a field name as a keyword

Package

oook.utils

Source

utils.lisp (file)

Function: update-owns-many INST RIGHT NEW

Remove all olds that are no longer in new, and add the new!

Package

oook.methods

Source

methods.lisp (file)

Function: update-timestamps INST

Update the ‘created-at’ and ‘last-modified’ timestamps in ‘inst’

Package

oook.methods

Source

methods.lisp (file)


Previous: , Up: Top   [Contents][Index]

Appendix A Indexes


Next: , Previous: , Up: Indexes   [Contents][Index]

A.1 Concepts

Jump to:   F   L   M   O  
Index Entry  Section

F
File, Lisp, oook.asd: The oook<dot>asd file
File, Lisp, oook/src/html.lisp: The oook/src/html<dot>lisp file
File, Lisp, oook/src/macro.lisp: The oook/src/macro<dot>lisp file
File, Lisp, oook/src/methods.lisp: The oook/src/methods<dot>lisp file
File, Lisp, oook/src/package.lisp: The oook/src/package<dot>lisp file
File, Lisp, oook/src/serialise.lisp: The oook/src/serialise<dot>lisp file
File, Lisp, oook/src/utils.lisp: The oook/src/utils<dot>lisp file

L
Lisp File, oook.asd: The oook<dot>asd file
Lisp File, oook/src/html.lisp: The oook/src/html<dot>lisp file
Lisp File, oook/src/macro.lisp: The oook/src/macro<dot>lisp file
Lisp File, oook/src/methods.lisp: The oook/src/methods<dot>lisp file
Lisp File, oook/src/package.lisp: The oook/src/package<dot>lisp file
Lisp File, oook/src/serialise.lisp: The oook/src/serialise<dot>lisp file
Lisp File, oook/src/utils.lisp: The oook/src/utils<dot>lisp file

M
Module, oook/src: The oook/src module

O
oook.asd: The oook<dot>asd file
oook/src: The oook/src module
oook/src/html.lisp: The oook/src/html<dot>lisp file
oook/src/macro.lisp: The oook/src/macro<dot>lisp file
oook/src/methods.lisp: The oook/src/methods<dot>lisp file
oook/src/package.lisp: The oook/src/package<dot>lisp file
oook/src/serialise.lisp: The oook/src/serialise<dot>lisp file
oook/src/utils.lisp: The oook/src/utils<dot>lisp file

Jump to:   F   L   M   O  

Next: , Previous: , Up: Indexes   [Contents][Index]

A.2 Functions

Jump to:   A   C   D   E   F   G   I   J   L   M   N   O   P   S   T   U   W  
Index Entry  Section

A
all-same-type-p: Internal functions

C
created-at: Exported generic functions

D
def-enhanced-printer: Exported macros
defmodel: Exported macros
destroy: Exported functions
do-each-owns-many: Internal macros

E
ensure-integer: Internal functions
ensure-slot-type: Internal macros

F
field-for-normal-slot: Internal functions
field-label-for: Internal functions
field-name-for: Internal functions
filter: Exported functions
find-by-id: Exported functions
foreign-key: Exported generic functions
from-alist: Exported functions
Function, all-same-type-p: Internal functions
Function, destroy: Exported functions
Function, ensure-integer: Internal functions
Function, field-for-normal-slot: Internal functions
Function, field-label-for: Internal functions
Function, field-name-for: Internal functions
Function, filter: Exported functions
Function, find-by-id: Exported functions
Function, from-alist: Exported functions
Function, gen-html-table: Exported functions
Function, get-edit-form: Exported functions
Function, get-slot-type: Internal functions
Function, make-clsql-base-slot: Internal functions
Function, make-clsql-join-slot: Internal functions
Function, make-clsql-key-slot: Internal functions
Function, make-foreign-key: Internal functions
Function, new-row-p: Internal functions
Function, parse-as-type: Exported functions
Function, pprint-model: Exported functions
Function, save: Exported functions
Function, search-like: Exported functions
Function, slot-type-without-null: Internal functions
Function, sql-field: Exported functions
Function, sql-field-keyword: Internal functions
Function, to-alist: Exported functions
Function, update-owns-many: Internal functions
Function, update-timestamps: Internal functions

G
gen-html-table: Exported functions
Generic Function, created-at: Exported generic functions
Generic Function, foreign-key: Exported generic functions
Generic Function, id: Exported generic functions
Generic Function, join-fks: Exported generic functions
Generic Function, last-modified: Exported generic functions
Generic Function, owns-many: Exported generic functions
Generic Function, owns-one: Exported generic functions
Generic Function, serialisable-fields: Exported generic functions
Generic Function, serialisable-joins: Exported generic functions
get-edit-form: Exported functions
get-slot-type: Internal functions

I
id: Exported generic functions

J
join-fks: Exported generic functions

L
last-modified: Exported generic functions

M
Macro, def-enhanced-printer: Exported macros
Macro, defmodel: Exported macros
Macro, do-each-owns-many: Internal macros
Macro, ensure-slot-type: Internal macros
Macro, with-record-type: Exported macros
Macro, with-serialisation-options: Exported macros
make-clsql-base-slot: Internal functions
make-clsql-join-slot: Internal functions
make-clsql-key-slot: Internal functions
make-foreign-key: Internal functions

N
new-row-p: Internal functions

O
owns-many: Exported generic functions
owns-one: Exported generic functions

P
parse-as-type: Exported functions
pprint-model: Exported functions

S
save: Exported functions
search-like: Exported functions
serialisable-fields: Exported generic functions
serialisable-joins: Exported generic functions
slot-type-without-null: Internal functions
sql-field: Exported functions
sql-field-keyword: Internal functions

T
to-alist: Exported functions

U
update-owns-many: Internal functions
update-timestamps: Internal functions

W
with-record-type: Exported macros
with-serialisation-options: Exported macros

Jump to:   A   C   D   E   F   G   I   J   L   M   N   O   P   S   T   U   W  

Next: , Previous: , Up: Indexes   [Contents][Index]

A.3 Variables

Jump to:   *  
S  
Index Entry  Section

*
*default-slot-type*: Exported special variables
*serialisation-options*: Exported special variables

S
Special Variable, *default-slot-type*: Exported special variables
Special Variable, *serialisation-options*: Exported special variables

Jump to:   *  
S  

Previous: , Up: Indexes   [Contents][Index]

A.4 Data types

Jump to:   O   P   S  
Index Entry  Section

O
oook: The oook system
oook: The oook package
oook.macro: The oook<dot>macro package
oook.methods: The oook<dot>methods package
oook.serialise: The oook<dot>serialise package
oook.utils: The oook<dot>utils package

P
Package, oook: The oook package
Package, oook.macro: The oook<dot>macro package
Package, oook.methods: The oook<dot>methods package
Package, oook.serialise: The oook<dot>serialise package
Package, oook.utils: The oook<dot>utils package

S
System, oook: The oook system

Jump to:   O   P   S