Basic couchdb state wrapper for sento. define simple couchdb services with sento.
  • Common Lisp 89.9%
  • Nix 10.1%
Find a file
2024-10-31 03:24:27 -04:00
source add files 2024-10-31 02:40:22 -04:00
.envrc add files 2024-10-31 02:40:22 -04:00
.gitignore ignore direnv 2024-10-31 02:40:39 -04:00
couchdb-sento.asd add files 2024-10-31 02:40:22 -04:00
flake.lock add files 2024-10-31 02:40:22 -04:00
flake.nix add files 2024-10-31 02:40:22 -04:00
LICENSE add files 2024-10-31 02:40:22 -04:00
README.org update readme 2024-10-31 03:24:27 -04:00
tasks.org add files 2024-10-31 02:40:22 -04:00

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")