PageRenderTime 62ms CodeModel.GetById 11ms app.highlight 46ms RepoModel.GetById 1ms app.codeStats 0ms

/README.md

http://github.com/sykopomp/chillax
Markdown | 518 lines | 311 code | 207 blank | 0 comment | 0 complexity | 8271bd83259889cb95abfedb20feedbd MD5 | raw file
  1# Quickstart example
  2
  3Chillax is [Quicklisp](http://quicklisp.org)-installable, allowing for super-quick, painless
  4installation of Chillax and all its dependencies.
  5
  6Make sure CouchDB is installed, and currently running. This example assumes that the server is
  7running in localhost, using the default 5984 port. Yason's alist encoder/decoder is used below to
  8make replies readable (by default, it uses hash tables as JSON objects, instead of alists, and
  9strings as keys).
 10
 11    CL-USER> (ql:quickload 'chillax)
 12             ...
 13             ...
 14             ...
 15    CL-USER> (in-package :chillax)
 16    CHILLAX> (defparameter *server* (make-instance 'yason-server :object-as-alist-p t
 17                                                   :parse-object-key-fun
 18                                                   (lambda (string) (intern string *package*))))
 19    *SERVER*
 20    CHILLAX> (defparameter *db* (ensure-db *server* "test"))
 21    *DB*
 22    CHILLAX> (all-documents *db*)
 23    ((|rows|) (|offset| . 0) (|total_rows| . 0))
 24    CHILLAX> (put-document *db* "my_test_doc" '((name . "Kat") (favorite-language . "common-lisp")))
 25    ((|rev| . "1-3c964cc898c03c48903a91d90b24a269")
 26     (|id| . "my_test_doc") (|ok| . T))
 27    CHILLAX> (get-document *db* "my_test_doc")
 28    ((FAVORITE-LANGUAGE . "common-lisp")
 29     (NAME . "Kat")
 30     (|_rev| . "1-3c964cc898c03c48903a91d90b24a269")
 31     (|_id| . "my_test_doc"))
 32    CHILLAX> (delete-document *db* (cdr (assoc '|_id| *)) (cdr (assoc '|_rev| *)))
 33    ((|rev| . "2-2221fc2b97c1fac1a82ba07d2835ac80")
 34     (|id| . "my_test_doc")
 35     (|ok| . T))
 36
 37# Introduction
 38
 39Chillax is a [CouchDB](http://couchdb.apache.org) abstraction layer for Common Lisp. It is **not** an
 40ORM or similar library, although it may be used to build such things.
 41
 42Chillax also includes a CouchDB view server, which can be used to write CouchDB views in full,
 43native Common Lisp.
 44
 45Chillax includes several systems:
 46
 47* chillax.asd - This is a 'DWIM' system. It includes the Yason server for parsing/encoding JSON
 48  data. It also defines a single `#:chillax` package that includes the symbols in both
 49  `#:chillax.core` and `#:chillax.yason`. If you don't know what you want, **this is probably what
 50  you want**.
 51* chillax.core.asd - Core API and protocols for servers, databases, documents, and
 52  design-docs.
 53* chillax.yason.asd - Implementation of the server protocol using Yason's JSON parser.
 54* chillax.jsown.asd - Implementation of the server protocol using JSOWN's JSON parser.
 55* chillax.utils.asd - Some handy utilities.
 56* chillax.view-server.asd - The Chillax view server. This only depends on chillax.utils.
 57
 58# About this document
 59
 60This README is not meant to document how to use CouchDB itself, or how to successfully design
 61applications with it. If you're new to CouchDB, it is recommended that you follow a guide (which can
 62be done while using Chillax).
 63
 64The [CouchDB Guide](http://guide.couchdb.org/) is recommended, and the
 65[CouchDB Wiki](http://wiki.apache.org/couchdb/) can be used as a general reference for CouchDB's
 66API.
 67
 68# Core API
 69
 70Chillax is a thin, lispy layer on top of CouchDB's RESTful API. Its main purpose is to provide Lisp
 71functions to all of CouchDB's API calls, while translating certain things into Lisp data and
 72concepts. For example, Chillax takes care of checking CouchDB's HTTP response codes for sanity. When
 73error codes are returned, Chillax will signal Lisp corresponding Lisp conditions.
 74
 75Additionally, Chillax is able to use any representation for CouchDB documents, provided the core
 76Chillax protocols are implemented for that representation, i.e, you can use hash tables, alists, or
 77instances of classes as your 'documents', and Chillax will automatically serialize/deserialize JSON
 78communications with CouchDB according to the protocol's implementation.
 79
 80Note that, since Chillax really is just a thin layer, it abstracts very little beyond the
 81above. Most Chillax functions will simply return the de-JSON-ified CouchDB responses, and leave you
 82to digging through the response objects for the data you need.
 83
 84## Server API
 85
 86Chillax's Server API provides access to server-level functionality. Server objects not only give
 87access to these database-independent features, but also act as mediators for all data that goes
 88through Chillax. Chillax's server objects are in charge, for example, of translating CouchDB's JSON
 89responses to and from whatever data format the user has chosen to use Lisp-side.
 90
 91Server objects are created through appropriate protocol implementations. See STANDARD-SERVER, and
 92YASON-SERVER below for the included implementations. Additional or alternate functionality for
 93serialization can easily be implemented through Chillax's server protocol.
 94
 95*[function]* `server-uri server`
 96
 97  Returns a string representation of the URL SERVER represents.
 98
 99
100*[function]* `all-dbs server`
101
102  Requests a list of all existing databases from SERVER.
103
104
105*[function]* `config-info server`
106
107  Requests the current configuration from SERVER.
108
109
110*[function]* `replicate server target &key create-target-p continuousp`
111
112  Replicates the database in SOURCE to TARGET. SOURCE and TARGET can both be either database names
113  in the local server, or full URLs to local or remote databases. If CREATE-TARGET-P is true, the
114  target database will automatically be created if it does not exist. If CONTINUOUSP is true,
115  CouchDB will continue propagating any changes in SOURCE to TARGET.
116
117
118*[function]* `stats server`
119
120  Requests general statistics from SERVER.
121
122
123*[function]* `active-tasks server`
124
125  Lists all the currently active tasks on SERVER.
126
127
128*[function]* `get-uuids server &key (number 10)`
129
130  Returns a list of NUMBER unique IDs requested from SERVER. The UUIDs generated by the server are
131  reasonably unique, but are not checked against existing UUIDs, so conflicts may still happen.
132
133
134## Database API
135
136Connecting to a database in Chillax involves creating a database object with one of 3 constructors,
137all of which accept a server object (see Server API above), and the name of the database.
138
139The Database API additionally provides some utility functions for accessing database-level
140functionality in CouchDB.
141
142Wiki: [HTTP Database API](http://wiki.apache.org/couchdb/HTTP_database_API)
143
144*[function]* `db-connect server name`
145
146  Confirms that a particular CouchDB database exists. If so, returns a new database object that can
147  be used to perform operations on it. Will signal a DB-NOT-FOUND error if the database does not
148  already exist.
149
150
151*[function]* `db-create server name`
152
153  Creates a new CouchDB database. Returns a database object that can be used to operate on it. Will
154  signal a DB-ALREADY-EXISTS error if there is already a database with the same NAME in SERVER.
155
156
157*[function]* `ensure-db server name`
158
159  Either connects to an existing database, or creates a new one. Returns two values: If a new
160  database was created, (DB-OBJECT T) is returned. Otherwise, (DB-OBJECT NIL).
161
162
163*[function]* `db-info db`
164
165  Fetches info about a given database from the CouchDB server.
166
167
168*[function]* `db-delete db`
169
170  Deletes a CouchDB database.
171
172
173*[function]* `db-compact db`
174
175  Triggers a database compaction.
176
177
178*[function]* `db-changes db`
179
180  Returns the changes feed for DB
181
182
183*[function]* `db-uri db`
184
185  Returns a string representing the full URI for DB.
186
187
188## Document API
189
190All document arguments to these functions must be Lisp objects that the database's server is able to
191encode to JSON. These functions will likewise return Lisp objects that represent the parsed JSON
192responses from CouchDB. Exact representations will depend on the server being used.
193
194Wiki: [HTTP Document API](http://wiki.apache.org/couchdb/HTTP_Document_API)
195
196*[function]* `get-document db id &key attachmentsp (errorpt)`
197
198  Finds a CouchDB document in DB, named by ID. PARAMS should be an alist containing the parameters
199for the HTTP GET request. If ATTACHMENTSP is TRUE, the document's attachments will be included in
200their entirety in their base64-encoded version. It is not recommended you use this unless you really
201know what you're doing. If ERRORP is NIL, GET-DOCUMENT will simply return NIL on 404.
202
203
204*[function]* `get-document-revision db doc-id &key (errorp t)`
205
206  Quickly fetches the latest revision for DOC-ID. If ERRORP is NIL, this can be used to quickly test
207  the existence of a document.
208
209
210*[function]* `put-document db id doc &key batch-ok-p`
211
212  Puts a document into DB, using ID. DOC must be Lisp data that DB's server is able to convert to
213  JSON.
214
215
216*[function]* `post-document db doc`
217
218  POSTs a document into DB. CouchDB will automatically assign a UUID if the document does not
219  already exist. Note that using this function is discouraged in the CouchDB documentation, since it
220  may result in duplicate documents because of proxies and other network intermediaries. If what you
221  need is to create a new document with a generated id, consider using GET-UUIDS with PUT-DOCUMENT.
222
223
224*[function]* `delete-document db id revision`
225
226  Deletes an existing document.
227
228
229*[function]* `copy-document from-id to-id &key revision`
230
231  Copies a document's content in-database.
232
233
234## Bulk Document API
235
236CouchDB supports a bulk document API for fetching, updating, and deleting documents in batches.
237
238Wiki: [HTTP Bulk Document API](http://wiki.apache.org/couchdb/HTTP_Bulk_Document_API)
239
240*[function]* `all-documents db &rest all-keys`
241
242  Requests the \_all\_docs document. ALL-KEYS correspond to GET-DOCUMENT's keyword arguments.
243
244
245*[function]* `batch-get-documents db &rest doc-ids`
246
247  Uses \_all\_docs to quickly fetch the given DOC-IDs in a single request. Note that this function
248  will NOT signal a DOCUMENT-NOT-FOUND error when one or more DOC-IDs are not found. Instead, the
249  results will be returned, and it's the user's responsibility to deal with any missing docs.
250
251
252*[function]* `bulk-post-documents documents &key all-or-nothing-p`
253
254  Allows you to update or submit multiple documents at the same time, using CouchDB's \_bulk\_docs
255  API. In order to delete a document through this API, the document must have a \_document attribute
256  with JSON 'true' as its value (note that what gets translated into 'true' depends on the server).
257
258  DOCUMENTS must be a sequence or sequence-like (depending on what DATA->JSON will do to it).
259
260  If ALL-OR-NOTHING-P is true, the entire submission will fail if a single one fails."
261
262
263## Standalone Attachment API
264
265CouchDB has an API for uploading and downloading standalone attachments.
266
267Wiki: [Standalone Attachments](http://wiki.apache.org/couchdb/HTTP_Document_API#Standalone_Attachments)
268
269*[function]* `put-attachment db doc-id attachment-name data &key rev content-type`
270
271  Adds DATA as an attachment. DATA can be a number of things:
272
273  * String or sequence of octets - DATA will be sent as-is directly to the server (using EXTERNAL-FORMAT-OUT for strings).
274  * Stream - The stream will be read until EOF is reached.
275  * Pathname - The file the pathname denotes will be opened and its data uploaded.
276  * Function designator - The corresponding function will be called with one argument, the stream to the server, to which it should send data.
277
278  If the document already exists, REV is required. This function can be used on non-existent
279  documents. If so, REV is not needed, and a document will be created automatically, and the
280  attachment associated with it.
281
282  The CONTENT-TYPE should be a string specifying the content type for DATA. (default: "application/octet-stream")
283
284
285*[function]* `get-attachment db doc-id attachment-name`
286
287  Returns 3 values:
288
289  1. STREAM - An open flexi-stream that can be READ. In order to read straight binary data, you must first fetch the underlying stream with FLEXI-STREAMS:FLEXI-STREAM-STREAM.
290  2. MUST-CLOSE-P - A boolean. If TRUE, the user must CLOSE this stream themselves once reading is done.
291  3. CONTENT-LENGTH - Declared content length for the incoming data.
292
293
294*[function]* `delete-attachment db doc-id attachment-name doc-revision`
295
296  Deletes an attachment from a document. DOC-REVISION must be the latest revision for the document.
297
298
299*[function]* `copy-attachment db doc-id attachment-name output-stream`
300
301  Copies data from the named attachment to OUTPUT-STREAM. Returns the number of bytes copied.
302
303
304## Design Document API
305
306Chillax currently includes a basic wrapper for Design Document-related operations. This API is
307likely to expand in the future as good ideas reveal themselves. Design documents will still need to
308be created through the regular document API.
309
310Wiki: [HTTP View API](http://wiki.apache.org/couchdb/HTTP_view_API)
311
312*[function]* `view-cleanup db`
313
314  Invokes \_view\_cleanup on DB. Old view output will remain on disk until this is invoked.
315
316
317*[function]* `compact-design-doc db design-doc-name`
318
319  Compaction can really help when you have very large views, very little space, or both.
320
321
322*[function]* `design-doc-info db design-doc-name`
323
324  Returns an object with various bits of status information. Refer to CouchDB documentation for
325  specifics on each value.
326
327
328*[function]* `query-view db design-doc-name view-name &key ... (see below) ...`
329
330  Queries view named by VIEW-NAME in DESIGN-DOC-NAME. Keyword arguments correspond to CouchDB view
331  query arguments.
332
333  * key - Single key to search for.
334  * multi-keys - Multiple keys to search for.
335  * startkey - When searching for a range of keys, the key to start from.
336  * endkey - When searching for a range of keys, the key to end at. Whether this is inclusive or not depends on inclusive-end-p (default: true)
337  * inclusive-end-p - If TRUE, endkey is included in the result. (default: true)
338  * startkey-docid - Like startkey, but keyed on the result documents' doc-ids.
339  * endkey-docid - Like endkey, but keyed on the result documents' doc-ids.
340  * limit - Maximum number of results to return.
341  * stalep - If TRUE, CouchDB will not refresh the view, even if it is stalled. (default: false)
342  * descendingp - If TRUE, will return reversed results. (default: false)
343  * skip - Number of documents to skip while querying.
344  * groupp - Controls whether the reduce function reduces to a set of distinct keys, or to a single result row.
345  * group-level - It's complicated. Google it!
346  * reducep - If FALSE, return the view without applying its reduce function (if any). (default: true)
347  * include-docs-p - If TRUE, includes the entire document with the result of the query. (default: false)
348
349
350*[function]* `query-temporary-view db &key (map (error)) reduce (language "javascript")`
351
352  Queries a temporary view. These views are meant to be for testing and development purposes, and
353  should _not_ be used in actual code.
354
355
356# Core Protocol
357
358You can use the core protocol to customize behavior of Chillax. Writing your own implementation for
359this protocol is relatively simple and painless, and it allows you to do things such as use your own
360custom JSON encoder/decoder, if Yason doesn't fit your needs. Classes that implement the protocols,
361and their behavior, is documented here, as well.
362
363For more information on the design of Chillax's protocol, refer to
364[Chillax and Protocols](http://sykosomatic.org/blog/?p=92).
365
366## Server Protocol
367
368Self-explanatory readers:
369
370* *[generic function]* `server-host server`
371* *[generic function]* `server-port server`
372* *[generic function]* `server-username server`
373* *[generic function]* `server-password server`
374* *[generic function]* `server-secure-p server`
375
376
377*[generic function]* `data->json server data &key`
378
379  Converts DATA to JSON suitable for sending to CouchDB.
380
381
382*[generic function]* `json->data server json &key`
383
384  Converts JSON to the desired data structure.
385
386
387*[generic function]* `make-db-object server name`
388
389  Creates an object which represents a database connection in SERVER. The object must conform to the
390  database protocol.
391
392
393### Included protocol implementations
394
395*[standard class]* `standard-server`
396
397  Basic implementation of the server protocol. JSON data is handled literally as strings, with no
398  conversion.
399
400  It supports the following initargs:
401
402  * :host - Host or IP address, in string form, of the CouchDB server. (default: "127.0.0.1")
403  * :port - Port, as an integer, for the CouchDB server. (default: 5984)
404  * :username - Username to use to authenticate with CouchDB server. (default: nil)
405  * :password - Password to use to authenticate with CouchDB server. (default: nil)
406  * :securep - Whether to use a secure SSL/TLS connection with the server. (default: nil)
407
408
409*[standard class]* `yason-server`
410
411  YASON-SERVERs use Yason's JSON parser/encoder to automatically translate content going to/coming
412  from the associated CouchDB server.
413
414  YASON-SERVER is a subclass of STANDARD-SERVER, and the same initargs apply.
415
416  It additionally supports the following initargs:
417
418  * :array-as-vector-p - If TRUE, parses JSON arrays as Lisp vectors. (default: nil)
419  * :boolean-as-symbol-p - If TRUE, parses JSON booleans as symbols instead of CL booleans. (default: nil)
420  * :object-as-alist-p - If TRUE, parses JSON objects as alists, instead of hash tables. (default: nil)
421  * :parse-object-key-fun - Function to process object keys with. (default: #'cl:identity)
422
423
424*[standard class]* `jsown-server`
425
426   JSOWN-SERVERs use JSOWN's JSON parser/encoder to automatically translate content going to/coming
427   from the associated CouchDB server.
428
429   JSOWN-SERVER is a subclass of STANDARD-SERVER, and the same initargs apply.
430
431
432*[function]* `call-with-key-container`
433
434  This function is part of the chillax.jsown package.
435
436  Calls FUNCTION, which require zero arguments, in a context where CONTAINER will be used for
437  jsown:parse-with-container.
438
439
440*[macro]* `with-key-container`
441
442  This macro is part of the chillax.jsown package.
443
444  Convenience macro for call-with-key-container.
445
446
447## Database Protocol
448
449*[generic function]* `database-server database`
450
451  Returns the server object with which DATABASE is associated.
452
453
454*[generic function]* `database-name database`
455
456  Returns the URL-encoded name of the database, a string. Note that CouchDB accepts certain
457  characters in database names -only- if they are URL-encoded (such as #\/). It is up to individual
458  implementations of DATABASE-NAME to implement this encoding.
459
460
461### Included protocol implementation
462
463*[standard class]* `standard-database`
464
465  Minimal, class-based implementation of the database protocol.
466
467
468# View Server
469
470The Chillax View Server allows you to write views in full-fledged Common Lisp. In order to use the
471server, you must create a binary using code loaded by chillax.view-server.asd, and make
472chillax-server::run-server the toplevel function.
473
474Once you put the binary in a place visible to the CouchDB process, add the following to
475/etc/couchdb/local.ini (or wherever your local.ini is located):
476
477    [query_servers]
478    common-lisp = /path/to/chillax-view-server
479
480Add the common-lisp entry if there's already a query\_servers entry.
481
482Once you've done this, you can start making queries directly in Lisp!
483
484    CHILLAX> (invoke-temporary-view *db* :language "common-lisp"
485                                         :map (prin1-to-string '(lambda (doc) (emit doc 1))))
486
487You can load anything you want into the view server image before dumping it, customize which package
488it executes views in, etc. The source code is fairly short and easy to digest. It's designed to be
489customizable for whatever your needs are.
490
491## Status
492
493Currently, the view server only provides basic features. A future release of Chillax will bring it
494back in sync with CouchDB's current line protocol.
495
496# Yason Problem
497
498Note that, at least on some systems, versions of [Yason](http://github.com/hanshuebner/Yason) prior
499to commit
500[00b9a5c06b7c4113a48518a1f136637efb4458b9](http://github.com/hanshuebner/Yason/commit/00b9a5c06b7c4113a48518a1f136637efb4458b9)
501will not work (in this commit, #\Return was added to the list of whitespace characters
502recognized). Using these versions instead of 0.1 is recommended anyway for performance reasons.
503
504# History
505
506The original author and current maintainer/developer of Chillax is
507[Kat Marchán](http://github.com/zkat); [Ian McEwen](http://github.com/ianmcorvidae)
508subsequently worked on CLOS bindings, since the original version was written for
509[Sheeple](http://github.com/zkat/sheeple). Chillax has since been mostly rewritten (again) to
510use a simple protocol-based extension API, allowing users to easily extend or alter Chillax's
511behavior, with minimal code.
512
513# Contributors
514
515* Kat Marchán <zkat at sykosomatic.org>
516* Adlai Chandrasekhar <munchking at gmail.com>
517* Ian McEwen <ianmcorvidae at ianmcorvidae.net>
518* Felix Lange <fjl at twurst.com>