The lambdalite Reference Manual

Table of Contents

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

The lambdalite Reference Manual

This is the lambdalite Reference Manual, version 1.0.1, generated automatically by Declt version 2.3 "Robert April" on Wed Mar 14 04:07:22 2018 GMT+0.


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

1 Introduction

LambdaLite

A functional, relational database in about 250 lines of Common Lisp.

SQL. NoSQL. ORMs. Key-value stores. There are a variety of approaches available for dealing with data. LambdaLite might be called functional and relational, for lack of better terms. The "relational" part is straightfoward: data is organized into tables. The "functional" part comes from a break with traditional SQL-style query languages: Lisp function closures are used to express queries over in-memory, in-process Lisp data.

Lisp Plug

People often ask "why Lisp?" It's hard to sum up all the benefits of Lisp in a few words. However, what LambdaLite does would be impossible in most languages. LambdaLite's where clauses are macros that seek out '/'-prefixed keywords and replace them with row attribute references. The resulting expression becomes a function closure that is compiled by most Lisp implementations into native code. Is that cool or what?

Motivation

Consider the following SQL query:

"SELECT * FROM USERS WHERE UPPER(name) = 'BOB'"

A few problems are apparent:

Under LambdaLite, we could instead write:

(select :users (where (equal (string-upcase :/name) "BOB")))

Why is this useful?

Notice that :/name begins with a slash; this is to distinguish it as a row attribute instead of an ordinary Lisp keyword.

Getting Started

LambdaLite is schemaless for flexibility. Rather than defining tables themselves, you define attributes that can be used on any table, using defattributes like so:

(defmacro str-member (&rest strings)
  `(lambda (x) (member x '(,@strings) :test #'string=)))

(defattributes
  :/ticket-id #'integerp
  :/title (lambda (x) (<= 1 (length x) 200))
  :/ticket-type (str-member "defect" "enhancement" "question")
  :/mocl-version (str-member "14.08" "14.05" "14.02" "13.08" "13.06" "n/a")
  :/target-os (str-member "iOS" "Android" "OS X" "n/a")
  :/dev-os (str-member "Mac OS X" "Linux 32-bit" "Linux 64-bit" "n/a")
  :/description (lambda (x) (<= 1 (length x) 64000))
  :/created-date
  :/created-by
  :/modified-date
  :/user-id
  :/display-name (lambda (x) (and x (<= 3 (length x) 20) (ppcre:scan "^[a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9]+$" x))))

This will define getter functions that can be used like (:/ticket-id row) as well as validation functions like (valid-title-p title).

Example Session

(require :lambdalite)
(use-package :lambdalite)
(load-db :path "~/db/")
(insert :cars '(:/car-id 1 :/make "Honda" :/color "blue")
              '(:/car-id 2 :/make "Ford" :/color "red"))
  => 2
(select :cars (where (equal :/color "red")))
  => ((:/CAR-ID 2 :/MAKE "Ford" :/COLOR "red"))
(defmacro str-member (&rest strings)
  `(lambda (x) (member x '(,@strings) :test #'string=)))
(defattributes
  :/car-id #'integerp 
  :/make #'stringp 
  :/color (str-member "red" "green" "blue"))
(valid-color-p "asdf")
  => nil
(dolist (row (select :cars)) 
  (format t "Make: ~A, Color: ~A~%" (:/make row) (:/color row)))
  >> Make: Honda, Color: blue
     Make: Ford, Color: red
(mapcar #':/color (select :cars))
  => ("blue" "red")
(insert :cars '(:/car-id 3 :/make "Toyota" :/color "green") 
              '(:/car-id 4 :/make "Audi" :/color "red"))
  => 2
(sort (select :cars) #'string< :key #':/make)
  => ((:/CAR-ID 4 :/MAKE "Audi" :/COLOR "red")
      (:/CAR-ID 2 :/MAKE "Ford" :/COLOR "red")
      (:/CAR-ID 1 :/MAKE "Honda" :/COLOR "blue")
      (:/CAR-ID 3 :/MAKE "Toyota" :/COLOR "green"))

Transactions

LambdaLite provides the with-tx macro to wrap transactions, which are executed serially across threads. For example, the following code is safe under a multi-threaded web server like Hunchentoot:

;; ... create a new ticket
(with-tx 
  (let ((user-id (logged-in-user-id))
        (ticket-id (1+ (length (select :tickets)))))
    (unless user-id 
      (error "Not logged in"))
    (insert :tickets (list :/ticket-id ticket-id :/created-by user-id :/ticket-status "open"))))

Any data commands that are used outside of a with-tx transaction will automatically be treated each individually as separate transactions.

Caveats

"Do things that don't scale" — Paul Graham

LambdaLite is completely unscalable — by design. Don't use it for heavy loads or large data sets. Even medium-sized jobs are a stretch. That's why 'Lite' is in the name.

Compatibility

Who is using LambdaLite?

LambdaLite powers the mocl support site at https://wukix.com/support/ with delightfully low query latency on a single Amazon EC2 micro instance.


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 lambdalite

Author

Wukix Inc <engineering@wukix.com>

License

MIT

Description

A functional, relational Lisp database

Long Description

A functional, relational database in about 250 lines of Common Lisp

Version

1.0.1

Dependencies
Source

lambdalite.asd (file)

Component

lambdalite.lisp (file)


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

3 Files

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


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

3.1 Lisp


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

3.1.1 lambdalite.asd

Location

lambdalite.asd

Systems

lambdalite (system)

Packages

lambdalite-asd


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

3.1.2 lambdalite/lambdalite.lisp

Parent

lambdalite (system)

Location

lambdalite.lisp

Packages

lambdalite

Exported Definitions
Internal Definitions

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

4 Packages

Packages are listed by definition order.


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

4.1 lambdalite-asd

Source

lambdalite.asd

Use List

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

4.2 lambdalite

Source

lambdalite.lisp (file)

Use List
Exported Definitions
Internal Definitions

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

5 Definitions

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


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

5.1 Exported definitions


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

5.1.1 Macros

Macro: defattributes &body BODY

Defines getter functions and validation functions for row attributes. Example:
(defattributes
:/item-id
:/title (lambda (x) (<= 1 (length x) 200)))
This would create the getter functions :/item-id and :/title, plus the validation function valid-title-p.

Package

lambdalite

Source

lambdalite.lisp (file)

Macro: keyset &rest KEY/VALUE-PAIRS

An ’update function’ for use in UPDATE. Example: (update :things (where foo) (keyset :/bar 1 :/baz 2))

Package

lambdalite

Source

lambdalite.lisp (file)

Macro: where EXPRESSION
Package

lambdalite

Source

lambdalite.lisp (file)

Macro: where-on ROW-BINDING EXPRESSION

Like WHERE, except giving direct access to the row, bound to ROW-BINDING. Unlike WHERE, EXPRESSION runs unmodified. Example: (select :users (where-on u (equal (:/age u) 30)))

Package

lambdalite

Source

lambdalite.lisp (file)

Macro: with-tx &body BODY

Execute a transaction as follows:
1. Every command that writes executes against a temporary table.
2. Back up the real target tables on disk.
3. Swap the target tables with the temporary ones in memory and persist.
4. If 3 does not complete, reverse the original swaps with the temporary tables and restore the backups as primary. 5. Delete backup files and temporary tables.

Package

lambdalite

Source

lambdalite.lisp (file)


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

5.1.2 Functions

Function: del NAME WHERE-PREDICATE

Usage: (del :foo (where ...))

Package

lambdalite

Source

lambdalite.lisp (file)

Function: insert NAME &rest ROWS

Example: (insert :users (:/user-id 1 :/name "Bob") (:/user-id 2 :/name "Alice"))

Package

lambdalite

Source

lambdalite.lisp (file)

Function: list-tables ()

Returns a list of table names (as keywords).

Package

lambdalite

Source

lambdalite.lisp (file)

Function: load-db &key PATH

Loads data files if they exist at PATH, or initializes an empty setup if not. Call once at startup.

Package

lambdalite

Source

lambdalite.lisp (file)

Function: select NAME &optional WHERE-PREDICATE

Example: (select :users (where (search "Bob" :/name)))

Package

lambdalite

Source

lambdalite.lisp (file)

Function: select1 NAME &optional WHERE-PREDICATE

Like SELECT, but returns the first row found.

Package

lambdalite

Source

lambdalite.lisp (file)

Function: update NAME WHERE-PREDICATE UPDATE-FUNCTION

Example: (update :things (where (evenp :/foo)) (keyset :/bar 1 :/baz 2))

Package

lambdalite

Source

lambdalite.lisp (file)


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

5.2 Internal definitions


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

5.2.1 Special variables

Special Variable: *db*
Package

lambdalite

Source

lambdalite.lisp (file)

Special Variable: *db-path*
Package

lambdalite

Source

lambdalite.lisp (file)

Special Variable: *tx*
Package

lambdalite

Source

lambdalite.lisp (file)

Special Variable: *tx-lock*
Package

lambdalite

Source

lambdalite.lisp (file)

Special Variable: *tx-modified-list*
Package

lambdalite

Source

lambdalite.lisp (file)


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

5.2.2 Macros

Macro: with-lock &body BODY
Package

lambdalite

Source

lambdalite.lisp (file)


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

5.2.3 Functions

Function: clone-temporary NAME
Package

lambdalite

Source

lambdalite.lisp (file)

Function: make-filename NAME
Package

lambdalite

Source

lambdalite.lisp (file)

Function: persist NAME &optional FILENAME
Package

lambdalite

Source

lambdalite.lisp (file)


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

Appendix A Indexes


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

A.1 Concepts

Jump to:   F   L  
Index Entry  Section

F
File, Lisp, lambdalite.asd: The lambdalite<dot>asd file
File, Lisp, lambdalite/lambdalite.lisp: The lambdalite/lambdalite<dot>lisp file

L
lambdalite.asd: The lambdalite<dot>asd file
lambdalite/lambdalite.lisp: The lambdalite/lambdalite<dot>lisp file
Lisp File, lambdalite.asd: The lambdalite<dot>asd file
Lisp File, lambdalite/lambdalite.lisp: The lambdalite/lambdalite<dot>lisp file

Jump to:   F   L  

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

A.2 Functions

Jump to:   C   D   F   I   K   L   M   P   S   U   W  
Index Entry  Section

C
clone-temporary: Internal functions

D
defattributes: Exported macros
del: Exported functions

F
Function, clone-temporary: Internal functions
Function, del: Exported functions
Function, insert: Exported functions
Function, list-tables: Exported functions
Function, load-db: Exported functions
Function, make-filename: Internal functions
Function, persist: Internal functions
Function, select: Exported functions
Function, select1: Exported functions
Function, update: Exported functions

I
insert: Exported functions

K
keyset: Exported macros

L
list-tables: Exported functions
load-db: Exported functions

M
Macro, defattributes: Exported macros
Macro, keyset: Exported macros
Macro, where: Exported macros
Macro, where-on: Exported macros
Macro, with-lock: Internal macros
Macro, with-tx: Exported macros
make-filename: Internal functions

P
persist: Internal functions

S
select: Exported functions
select1: Exported functions

U
update: Exported functions

W
where: Exported macros
where-on: Exported macros
with-lock: Internal macros
with-tx: Exported macros

Jump to:   C   D   F   I   K   L   M   P   S   U   W  

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

A.3 Variables

Jump to:   *  
S  
Index Entry  Section

*
*db*: Internal special variables
*db-path*: Internal special variables
*tx*: Internal special variables
*tx-lock*: Internal special variables
*tx-modified-list*: Internal special variables

S
Special Variable, *db*: Internal special variables
Special Variable, *db-path*: Internal special variables
Special Variable, *tx*: Internal special variables
Special Variable, *tx-lock*: Internal special variables
Special Variable, *tx-modified-list*: Internal special variables

Jump to:   *  
S  

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

A.4 Data types

Jump to:   L   P   S  
Index Entry  Section

L
lambdalite: The lambdalite system
lambdalite: The lambdalite package
lambdalite-asd: The lambdalite-asd package

P
Package, lambdalite: The lambdalite package
Package, lambdalite-asd: The lambdalite-asd package

S
System, lambdalite: The lambdalite system

Jump to:   L   P   S