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