Next: Introduction, Previous: (dir), Up: (dir) [Contents][Index]
This is the lambdalite Reference Manual, version 1.0.1, generated automatically by Declt version 3.0 "Montgomery Scott" on Tue Dec 22 13:58:10 2020 GMT+0.
• Introduction | What lambdalite is all about | |
• Systems | The systems documentation | |
• Files | The files documentation | |
• Packages | The packages documentation | |
• Definitions | The symbols documentation | |
• Indexes | Concepts, functions, variables and data types |
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.
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?
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.
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)
.
(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"))
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.
"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.
LambdaLite powers the mocl support site at https://wukix.com/support/ with delightfully low query latency on a single Amazon EC2 micro instance.
Next: Files, Previous: Introduction, Up: Top [Contents][Index]
The main system appears first, followed by any subsystem dependency.
• The lambdalite system |
Wukix Inc <engineering@wukix.com>
MIT
A functional, relational Lisp database
A functional, relational database in about 250 lines of Common Lisp
1.0.1
lambdalite.asd (file)
lambdalite.lisp (file)
Files are sorted by type and then listed depth-first from the systems components trees.
• Lisp files |
• The lambdalite.asd file | ||
• The lambdalite/lambdalite.lisp file |
Next: The lambdalite/lambdalite․lisp file, Previous: Lisp files, Up: Lisp files [Contents][Index]
lambdalite.asd
lambdalite (system)
Previous: The lambdalite․asd file, Up: Lisp files [Contents][Index]
lambdalite (system)
lambdalite.lisp
Next: Definitions, Previous: Files, Up: Top [Contents][Index]
Packages are listed by definition order.
• The lambdalite-asd package | ||
• The lambdalite package |
Next: The lambdalite package, Previous: Packages, Up: Packages [Contents][Index]
lambdalite.asd
Previous: The lambdalite-asd package, Up: Packages [Contents][Index]
lambdalite.lisp (file)
Definitions are sorted by export status, category, package, and then by lexicographic order.
• Exported definitions | ||
• Internal definitions |
Next: Internal definitions, Previous: Definitions, Up: Definitions [Contents][Index]
• Exported macros | ||
• Exported functions |
Next: Exported functions, Previous: Exported definitions, Up: Exported definitions [Contents][Index]
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.
lambdalite.lisp (file)
An ’update function’ for use in UPDATE. Example: (update :things (where foo) (keyset :/bar 1 :/baz 2))
lambdalite.lisp (file)
lambdalite.lisp (file)
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)))
lambdalite.lisp (file)
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.
lambdalite.lisp (file)
Previous: Exported macros, Up: Exported definitions [Contents][Index]
Usage: (del :foo (where ...))
lambdalite.lisp (file)
Example: (insert :users (:/user-id 1 :/name "Bob") (:/user-id 2 :/name "Alice"))
lambdalite.lisp (file)
Returns a list of table names (as keywords).
lambdalite.lisp (file)
Loads data files if they exist at PATH, or initializes an empty setup if not. Call once at startup.
lambdalite.lisp (file)
Example: (select :users (where (search "Bob" :/name)))
lambdalite.lisp (file)
Like SELECT, but returns the first row found.
lambdalite.lisp (file)
Example: (update :things (where (evenp :/foo)) (keyset :/bar 1 :/baz 2))
lambdalite.lisp (file)
Previous: Exported definitions, Up: Definitions [Contents][Index]
• Internal special variables | ||
• Internal macros | ||
• Internal functions |
Next: Internal macros, Previous: Internal definitions, Up: Internal definitions [Contents][Index]
lambdalite.lisp (file)
lambdalite.lisp (file)
lambdalite.lisp (file)
lambdalite.lisp (file)
lambdalite.lisp (file)
Next: Internal functions, Previous: Internal special variables, Up: Internal definitions [Contents][Index]
lambdalite.lisp (file)
Previous: Internal macros, Up: Internal definitions [Contents][Index]
lambdalite.lisp (file)
lambdalite.lisp (file)
lambdalite.lisp (file)
Previous: Definitions, Up: Top [Contents][Index]
• Concept index | ||
• Function index | ||
• Variable index | ||
• Data type index |
Next: Function index, Previous: Indexes, Up: Indexes [Contents][Index]
Jump to: | F L |
---|
Jump to: | F L |
---|
Next: Variable index, Previous: Concept index, Up: Indexes [Contents][Index]
Jump to: | C D F I K L M P S U W |
---|
Jump to: | C D F I K L M P S U W |
---|
Next: Data type index, Previous: Function index, Up: Indexes [Contents][Index]
Jump to: | *
S |
---|
Jump to: | *
S |
---|
Previous: Variable index, Up: Indexes [Contents][Index]
Jump to: | L P S |
---|
Jump to: | L P S |
---|