Basic couchdb state wrapper for sento. define simple couchdb services with sento.
- Common Lisp 89.9%
- Nix 10.1%
| source | ||
| .envrc | ||
| .gitignore | ||
| couchdb-sento.asd | ||
| flake.lock | ||
| flake.nix | ||
| LICENSE | ||
| README.org | ||
| tasks.org | ||
Readme
Couchdb sento
Couchdb sento was created to wrap up a CL-COUCH client.
Install
(ql:quickload :couchdb-sento)
| :COUCHDB-SENTO |
Example
Setup couchdb with docker
Note that this is a older image, but bundles a fts index service
mkdir -p $PWD/.database && sudo chown 1001:1001 $PWD/.database && docker run -d -e COUCHDB_USER=admin -e COUCHDB_PASSWORD=password -v $PWD/.database:/opt/couchdb/data -p 0.0.0.0:5984:5984 ibmcom/couchdb3
Define gets/puts using the make-service functions.
(uiop:define-package :couchdb-sento-example
(:use :couchdb-sento :cl :cl-couch)
(:documentation "Examples for couchdb-sento"))
(in-package :couchdb-sento-example)
(defvar *sys* (asys:make-actor-system))
(defvar *couchdb-agent* (make-couchdb-agent *sys*))
(defvar *puts* (make-insert-service *couchdb-agent* *sys* "puts"))
(defvar *gets* (make-get-service *couchdb-agent* *sys* "gets"))
(defvar *doc-id* 0)
*DOC-ID*
Put a document, ommiting the json key _id will have couchdb generate one for you, which will be included in the response along with the _rev key.
This example creates a new document couch? returns a future
(couch? *puts* 5 :database "testing" :document (jsown:to-json
(jsown:new-js
("_id" (format nil "~a" (incf *doc-id*)))
("data" (dex:get "http://httpbin.org/links/60/1")))))
#<SENTO.FUTURE:FUTURE promise: #<PROMISE finished: NIL errored: NIL forward: NIL {100FC880C3}>>
(future:fcompleted
(couch? *gets* 5 :database "testing" :id (format nil "~a" *doc-id*))
(result)
(format t "The rev is: ~a" (jsown:val (jsown:parse result) "_rev")))
#<SENTO.FUTURE:FUTURE promise: #<PROMISE finished: NIL errored: NIL forward: NIL {100F08A603}>>
You can also define your own service. I only made the most basic actors for common tasks.
Here is a simple actor that querys a full text index.
(defun make-fts-service (agent system name)
(define-couchdb-service (agent system client :actor-name name)
(cl-couch:fts-search client (jsown:to-json
(jsown:new-js
("q" (get-arg :q))
("limit" (or (get-arg :limit) 25))
("include-docs" "false"))) (get-arg :database) (get-arg :ddoc) (get-arg :view-name))))
And here is what the macro expands to
(sento.actor-context:actor-of system :name name :receive
(lambda (#:msg4767)
(sento.tasks:with-context (system :shared)
(let* ((couchdb-sento::*msg* #:msg4767)
(#:sender4768 sento.actor:*sender*)
(couchdb-sento::fut
(sento.future:with-fut
(with-couchdb-agent (client agent)
(flet ((couchdb-sento::get-arg
(couchdb-sento::arg)
(getf
couchdb-sento::*msg*
couchdb-sento::arg)))
(fts-search client
(jsown:to-json
(jsown:new-js
("q"
(get-arg :q))
("limit"
(or
(get-arg
:limit)
25))
("include-docs"
"false")))
(get-arg :database)
(get-arg :ddoc)
(get-arg
:view-name)))))))
(sento.future:fcompleted couchdb-sento::fut
(couchdb-sento::result)
(sento.actor:reply couchdb-sento::result
#:sender4768))))))
Get arge is a flet that graps a plist key.
Messages are assumed to be in plists form. example get msg
'(:id "example_id" :database "database-name" :rev "optional-rev")