From peddy at common-lisp.net Sat Feb 16 19:36:07 2008 From: peddy at common-lisp.net (peddy) Date: Sat, 16 Feb 2008 14:36:07 -0500 (EST) Subject: [clouchdb-cvs] CVS clouchdb/public_html Message-ID: <20080216193607.26AFC1605A@common-lisp.net> Update of /project/clouchdb/cvsroot/clouchdb/public_html In directory clnet:/tmp/cvs-serv13173/public_html Modified Files: index.html Log Message: - Updated docs to reflect 0.0.8 release - Remove some junk code - Updated example to demonstrate use of query-document --- /project/clouchdb/cvsroot/clouchdb/public_html/index.html 2008/01/19 20:18:57 1.13 +++ /project/clouchdb/cvsroot/clouchdb/public_html/index.html 2008/02/16 19:36:06 1.14 @@ -27,7 +27,7 @@
- Author: Peter Eddy (peter.eddy at the gmail.com) + Author: Peter Eddy (peter.eddy at gmail.com)
(asdf:oos 'asdf:load-op '#:clouchdb-examples) (in-package :clouchdb-examples) -(example1) -(example2)
- Be sure to look at examples.lisp to understand what each example is doing. + The file examples.lisp contains comments describing each example in detail.
NB: If you try these examples I suggest also viewing the results via - CouchDb's HTML UI - at http://localhost:8888/_utils/browse/index.html, - (or http://localhost:5984/_utils/browse/index.html - if you're using ClouchDb version 7.2 or later), of course you'll need to - adjust the URL for the actual CouchDb server and port in use. + CouchDb's bulit-in HTML UI + at http://localhost:8888/_utils/browse/index.html, + (or http://localhost:5984/_utils/browse/index.html + if you're using ClouchDb versions prior to 7.2), of course you'll + need to adjust the URL for the actual CouchDb server and port in + use.
;; Create, or drop and recreate, the current database CLOUCHDB-USER> (create-db :if-exists :recreate) -((:OK . T)) +((:|ok| . T)) ;; Create a document that will have it's ID assigned by the CouchDb server CLOUCHDB-USER> (create-document '((:size . "medium") (:color . "blue"))) -((:OK . T) (:ID . "C731D3A3698DA144FB35EDA9737917F2") (:REV . "3363852140")) +((:|ok| . T) (:|id| . "C731D3A3698DA144FB35EDA9737917F2") (:|rev| . "3363852140")) ;; CouchDb generated IDs are too large to use easily in an ;; interactive example like this, so create another document ;; with a shorter ID to demonstrate property value updates CLOUCHDB-USER> (create-document '((:size . "large") (:color . "blue")) :id "someid") -((:OK . T) (:ID . "someid") (:REV . "3181950830")) +((:|ok| . T) (:|id| . "someid") (:|rev| . "3181950830")) ;; Change :color property CLOUCHDB-USER> (let ((doc (get-document "someid"))) (setf (document-property :color doc) "green") (put-document doc)) -((:OK . T) (:ID . "someid") (:REV . "4275808446")) +((:|ok| . T) (:|id| . "someid") (:|rev| . "4275808446")) ;; Show that the new property stuck CLOUCHDB-USER> (get-document "someid") -((:_ID . "someid") (:_REV . "4275808446") (:SIZE . "large") (:COLOR . "green")) +((:|_id| . "someid") (:|_rev| . "4275808446") (:SIZE . "large") (:COLOR . "green")) ;; Get revision information for this document (formatted for legibility) CLOUCHDB-USER> (get-document "someid" :revision-info t) -((:_ID . "someid") (:_REV . "4275808446") (:SIZE . "large") (:COLOR . "green") - (:_REVS_INFO - ((:REV . "4275808446") (:STATUS . "disk")) - ((:REV . "3181950830") (:STATUS . "disk")))) +((:|_id| . "someid") (:|_rev| . "4275808446") (:SIZE . "large") (:COLOR . "green") + (:|_rev|S_INFO + ((:|rev| . "4275808446") (:STATUS . "disk")) + ((:|rev| . "3181950830") (:STATUS . "disk")))) ;; Since the first revision is still available (:status . "disk") we ;; can still retrieve it CLOUCHDB-USER> (get-document "someid" :revision "3181950830") -((:_ID . "someid") (:_REV . "3181950830") (:SIZE . "large") (:COLOR . "blue")) +((:|_id| . "someid") (:|_rev| . "3181950830") (:SIZE . "large") (:COLOR . "blue")) ;; In the following document, the :tags field has an array value, ;; the :demographics field has a map value, and the :religion map @@ -294,10 +320,10 @@ (:protestant . 2.5))) (:political-system . "democracy")))) :id "czechrepublic") -((:OK . T) (:ID . "czechrepublic") (:REV . "4272625130")) +((:|ok| . T) (:|id| . "czechrepublic") (:|rev| . "4272625130")) ;; Let's see what this document looks like (formatted for legibility) CLOUCHDB-USER> (get-document "czechrepublic") -((:_ID . "czechrepublic") (:_REV . "3929202819") +((:|_id| . "czechrepublic") (:|_rev| . "3929202819") (:NAME . "Czech Republic") (:TAGS "country" "european") (:DEMOGRAPHICS (:POPULATION . 10230000) (:RELIGION (:AGNOSTIC . 0.59) (:ROMAN-CATHOLIC . 0.26) (:PROTESTANT . 2.5)) @@ -306,17 +332,17 @@ CLOUCHDB-USER> (get-all-documents) ((:TOTAL_ROWS . 3) (:OFFSET . 0) (:ROWS - ((:ID . "C731D3A3698DA144FB35EDA9737917F2") (:KEY . "C731D3A3698DA144FB35EDA9737917F2") - (:VALUE (:REV . "3363852140"))) - ((:ID . "czechrepublic") (:KEY . "czechrepublic") (:VALUE (:REV . "4272625130"))) - ((:ID . "someid") (:KEY . "someid") (:VALUE (:REV . "4275808446"))))) + ((:|id| . "C731D3A3698DA144FB35EDA9737917F2") (:KEY . "C731D3A3698DA144FB35EDA9737917F2") + (:VALUE (:|rev| . "3363852140"))) + ((:|id| . "czechrepublic") (:KEY . "czechrepublic") (:VALUE (:|rev| . "4272625130"))) + ((:|id| . "someid") (:KEY . "someid") (:VALUE (:|rev| . "4275808446")))))
Demonstrating:
(create-document '((:name . "Max") (:agent . 86)) :id "agent86") (get-document "agent86") -=> ((:_ID . "agent86") (:_REV . "3674093994") (:NAME . "Max") (:AGENT . 86)) +=> ((:|_id| . "agent86") (:|_rev| . "3674093994") (:NAME . "Max") (:AGENT . 86))
@@ -572,35 +603,30 @@
Field names in CouchDb are case sensitive. Field names specified - with keyword symbols are normally converted to or from lower case - in communication with the CouchDb server, however it is possible - to specify case in field names like so: + with unquoted keyword symbols are normally to upper case, and + result in upper case field names in the CouchDb server. Use symbol + name quotes to specify mixed or lower case field names like so:
;; Create a document with a mixed case field name. This document -;; will appear in the database as, "fieldName" -(create-document '((:field-name . "Value")) :id "mixed-case1") +;; will appear in the database as, "MixedCaseName" +(create-document '((:|MixedCaseName| . "Value")) :id "mixed-case1") (get-document "mixed-case1") -=> ((:_ID . "mixed-case1") (:_REV . "2016717365") (:*FIELD-NAME . "Value")) +=> ((:|_id| . "mixed-case1") (:|_rev| . "2016717365") (:|MixedCaseName| . "Value"))
- But see Issues and Bugs -
- -The native document representation in the CouchDb protocol is - a JSON object. Using - cl-json, - clouchdb automatically translates documents between JSON and Lisp - associative lists. + a JSON object. Clouchdb + automatically translates documents between JSON and Lisp + associative lists.
The value of a document field may be a string, a number, a list, or an associative list. Document field values may be nested to - create very complex document structures. + create arbitrarily complex document structures.
@@ -630,10 +656,10 @@(create-document '((:name . "Maxwell Smart") (:agent . 86)) :id "max") -=> ((:OK . T) (:ID . "max") (:REV . "3789799231")) +=> ((:|ok| . T) (:|id| . "max") (:|rev| . "3789799231")) (get-document "max") -=> ((:_ID . "max") (:_REV . "3789799231") (:NAME . "Maxwell Smart") (:AGENT . 86)) +=> ((:|_id| . "max") (:|_rev| . "3789799231") (:NAME . "Maxwell Smart") (:AGENT . 86))@@ -656,21 +682,20 @@ Example:- ;; No case encoding - (as-keyword-symbol "normal") - => :NORMAL + ;; Lower case + (as-keyword-symbol "lowercase") + => :|lowercase| ;; Upper case (as-keyword-symbol "UPPER-CASE") - => :-U-P-P-E-R--C-A-S-E + => :UPPER-CASE ;; Mixed case (as-keyword-symbol "MixedCase") - =>:-MIXED-CASE + =>:|MixedCase|See (as-field-name-string) - and Issues and Bugs
@@ -688,21 +713,20 @@ Example:- ;; No case encoding - (as-field-name-string :normal) - => "normal" - ;; Upper case - (as-field-name-string :-u-p-p-e-r--c-a-s-e) - => "UPPER-CASE" + (as-field-name-string :case) + => "CASE" + + ;; Lower case + (as-field-name-string :|case|) + => "case" ;; Mixed case - (as-field-name-string :-Mixed-Case) [190 lines skipped] From peddy at common-lisp.net Sat Feb 16 19:36:07 2008 From: peddy at common-lisp.net (peddy) Date: Sat, 16 Feb 2008 14:36:07 -0500 (EST) Subject: [clouchdb-cvs] CVS clouchdb/src Message-ID: <20080216193607.A18AB6308A@common-lisp.net> Update of /project/clouchdb/cvsroot/clouchdb/src In directory clnet:/tmp/cvs-serv13173/src Modified Files: clouchdb.lisp examples.lisp Log Message: - Updated docs to reflect 0.0.8 release - Remove some junk code - Updated example to demonstrate use of query-document --- /project/clouchdb/cvsroot/clouchdb/src/clouchdb.lisp 2008/01/19 20:23:53 1.20 +++ /project/clouchdb/cvsroot/clouchdb/src/clouchdb.lisp 2008/02/16 19:36:07 1.21 @@ -202,22 +202,6 @@ (write-string "%20" s)) (t (format s "%~2,'0x" (char-code c))))))) -;; (defun alist-to-url-encoded-string (alist &key (external-format +utf-8+)) -;; "ALIST is supposed to be an alist of name/value pairs where both -;; names and values are strings. This function returns a string where -;; this list is represented as for the content type -;; `application/x-www-form-urlencoded', i.e. the values are URL-encoded -;; using the external format EXTERNAL-FORMAT, the pairs are joined with a -;; #\\& character, and each name is separated from its value with a #\\= -;; character." -;; (with-output-to-string (out) -;; (loop for first = t then nil -;; for (name . value) in alist -;; unless first do (write-char #\& out) -;; do (format out "~A=~A" -;; (url-encode name :external-format external-format) -;; (url-encode value :external-format external-format))))) - (defun make-uri (&rest rest) "Return a URI containing *protocol*://*host*:*port*/ and the concatenation of the remaining parameters." @@ -297,14 +281,25 @@ (t (rplacd (assoc name doc) value))) doc)) -(defun set-document-property (doc name value) +;; (defun set-document-property (doc name value) +;; "Set a property of a document. If the named property does not exist, +;; add it to the document, otherwise change the existing value. Does not +;; destructively modify input document, so be sure to use return value." +;; (let ((doc (copy-tree doc))) +;; (if (assoc name doc) +;; (setf (document-property name doc) value) +;; (cons `(,(as-keyword-symbol name) . ,value) doc)))) + +(defun set-document-property (doc &rest args) "Set a property of a document. If the named property does not exist, add it to the document, otherwise change the existing value. Does not destructively modify input document, so be sure to use return value." (let ((doc (copy-tree doc))) - (if (assoc name doc) - (setf (document-property name doc) value) - (cons `(,(as-keyword-symbol name) . ,value) doc)))) + (loop for (name value) on args by #'cddr + do (if (assoc name doc) + (setf (document-property name doc) value) + (setf doc (cons `(,(as-keyword-symbol name) . ,value) doc)))) + doc)) (defun document-id (doc) "Shortcut for getting the ID from the specified document. First @@ -338,7 +333,7 @@ document or null." (let ((res)) (labels ((q (query doc rec) - ;;(format t "~%test: r=~s, query=~s doc=~s~%" rec query doc) +;; (format t "~%test: r=~s, query=~s doc=~s~%" rec query doc) (cond ((null doc) nil) ((null query) --- /project/clouchdb/cvsroot/clouchdb/src/examples.lisp 2007/12/28 16:25:51 1.6 +++ /project/clouchdb/cvsroot/clouchdb/src/examples.lisp 2008/02/16 19:36:07 1.7 @@ -55,7 +55,7 @@ (create-db :if-exists :recreate) ;; Create a document with ID of "haussmann" (create-document '(;; Fields with scalar values: - (:name . "Georges-Eug?ne Haussmann") + (:name . "Georges-Eug??ne Haussmann") (:aka . "Baron Haussmann") (:born . "1809-03-27") (:died . "1891-01-11")) @@ -128,5 +128,109 @@ (document-property :id doc) doc))))) - - \ No newline at end of file +(defun example3 () + "Demonstrate the use of (query-document). Create a database, +populate it with some documents representing countries, +use (query-document) to operate on this data." + (with-connection (:db-name "example3") + (create-db :if-exists :recreate) + (create-document '((:name . "Czech Republic") + (:tags . ("country" "european")) + (:motto . "Truth prevails") + (:demographics . ((:population . 10230000) + (:capital . "Prague") + (:eu-accession . "2004-05-01") + (:president . "V??clav Klaus") + (:prime-minister . "Mirek Topol??nek")))) + :id "czechrepublic") + (create-document '((:name . "France") + (:tags . ("country" "european")) + (:motto . "Libert??, ??galit??, Fraternit??") + (:demographics . ((:population . 64473140) + (:capital . "Paris") + (:eu-accession . "1957-03-25") + (:president . "Nicolas Sarkozy") + (:prime-minister . "Fran??ois Fillon")))) + :id "france") + (create-document '((:name . "Italy") + (:tags . ("country" "european")) + (:motto . "Il Canto degli Italiani") + (:demographics . ((:population . 59337888) + (:capital . "Rome") + (:eu-accession . "1957-03-17") + (:president . "Giorgio Napolitano") + (:prime-minister . "Romano Prodi")))) + :id "italy") + (create-document '((:name . "Turkey") + (:tags . ("country" "eurasian")) + (:motto . "Yurtta Sulh, Cihanda Sulh") + (:demographics . ((:population . 70586256) + (:capital . "Ankara") + (:prime-minister . "Recep Tayyip Erdo??an") + (:president . "Abdulla G??l")))) + :id "turkey") + ;; (get-all-documents) returns information about all documents in + ;; the database: + ;; + ;; ((:|total_rows| . 3) + ;; (:|offset| . 0) + ;; (:|rows| + ;; ((:|id| . "turkey") + ;; (:|key| . "turkey") + ;; (:|value| (:|rev| . "1081123848"))) + ;; ((:|id| . "czechrepublic") + ;; (:|key| . "czechrepublic") + ;; (:|value| (:|rev| . "3192261183"))) + ;; ((:|id| . "france") + ;; (:|key| . "france") + ;; (:|value| (:|rev| . "3199678281"))) + ;; ((:|id| . "italy") + ;; (:|key| . "italy") + ;; (:|value| (:|rev| . "2716436578"))))) + ;; + ;; The first use of (query-document) below retuns a list of + ;; document IDs (:|id|) values extracted from the alist values in + ;; :|rows|: + ;; + ;; (query-document '(:|rows| :|id|) (get-all-documents)) + ;; ==> ("turkey" "italy" "france" "czechrepublic") + ;; + ;; This list is then iterated and the country document ID is used + ;; to fetch the actual country document using (get-document). + ;; + ;; The second use of (query-document) below operates on individual + ;; country documents and recursively (:**) searches document + ;; properties for the :eu-accession values: + ;; + ;; (query-document '(:** :eu-accession) (get-document "france")) + ;; ==> ("1957-03-25") + ;; + ;; Alternatively this query could be expressed: + ;; '(:demographics :eu-accession). + ;; + ;; This will produce the following output: + ;; + ;; Country: turkey, EU accession: NIL + ;; Country: italy, EU accession: 1957-03-17 + ;; Country: france, EU accession: 1957-03-25 + ;; Country: czechrepublic, EU accession: 2004-05-01 + ;; + (dolist (country (query-document '(:|rows| :|id|) (get-all-documents))) + (format t "Country: ~a, EU accession: ~a~%" country + (car (query-document '(:** :eu-accession) (get-document country))))) + ;; + ;; It's possible to use a function in the query argument list of + ;; (query-document). The following example will return a list of + ;; all country presidents: + ;; + ;; ("Abdulla G??l" "Giorgio Napolitano" "Nicolas Sarkozy" "V??clav Klaus") + ;; + ;; In this example the clouchdb function (get-document) is applied + ;; to all ID values found matching the previous :|id| query + ;; paramater, extracted from the (get-all-documents) results. The + ;; remainder of the query expression is applied to the function + ;; result, which in this case is the fetched country document. + ;; + ;; Note the leading backquote in the query argument list + ;; + (query-document `(:|rows| :|id| ,#'get-document :** :president) (get-all-documents)))) \ No newline at end of file From peddy at common-lisp.net Sat Feb 16 19:53:49 2008 From: peddy at common-lisp.net (peddy) Date: Sat, 16 Feb 2008 14:53:49 -0500 (EST) Subject: [clouchdb-cvs] CVS clouchdb/public_html Message-ID: <20080216195349.6806E640B5@common-lisp.net> Update of /project/clouchdb/cvsroot/clouchdb/public_html In directory clnet:/tmp/cvs-serv17435 Modified Files: index.html Log Message: - Fixed some invalid HTML --- /project/clouchdb/cvsroot/clouchdb/public_html/index.html 2008/02/16 19:36:06 1.14 +++ /project/clouchdb/cvsroot/clouchdb/public_html/index.html 2008/02/16 19:53:49 1.15 @@ -868,6 +868,7 @@[Function]
query-document query document +This function can be used to easily extract data from complex @@ -971,7 +972,7 @@
[Function]
+set-document-property doc &rest args
-set-document-property doc &rest argsModify or add property values to a document. This function returns a From peddy at common-lisp.net Mon Feb 18 03:16:02 2008 From: peddy at common-lisp.net (peddy) Date: Sun, 17 Feb 2008 22:16:02 -0500 (EST) Subject: [clouchdb-cvs] CVS clouchdb/public_html Message-ID: <20080218031602.1FA1C5D18C@common-lisp.net> Update of /project/clouchdb/cvsroot/clouchdb/public_html In directory clnet:/tmp/cvs-serv13099 Modified Files: index.html Log Message: Lots of minor fixes and corrections --- /project/clouchdb/cvsroot/clouchdb/public_html/index.html 2008/02/16 19:53:49 1.15 +++ /project/clouchdb/cvsroot/clouchdb/public_html/index.html 2008/02/18 03:16:01 1.16 @@ -51,7 +51,8 @@
- Feb 16, 2008 Released version 0.0.8 with the following - significant changes: + significant changes. Please read if you're updating from prior + versions.
- Changed document field name encoding to get rid of cl-json/parenscript style * and - case encoding. Now using the @@ -60,8 +61,10 @@ never get it right on the first try). Note: This will break existing code wherever there is this case sensitivity, especially in standard CouchDb property names - like :ID, :|_id|, :REV, :_REV, which are now :|id|, :|_id|, - :|rev| and :|_rev|. Sorry about that. + like :ID, :_ID, :REV, and :_REV, which are now :|id|, :|_id|, + :|rev| and :|_rev|. Sorry about this. On the bright side you + should never have to deal with field names like + :*A-L-L-U-P-P-E-R-C-A-S-E again.
- Changed (set-document-property) so that it no longer modifies its document, but instead returns a copy with @@ -70,7 +73,7 @@ return value from this function.
- Added query-document - function, making it easier to extract data from complex + function to make it easier to extract data from complex documents.
- @@ -603,24 +606,24 @@
Field names in CouchDb are case sensitive. Field names specified - with unquoted keyword symbols are normally to upper case, and - result in upper case field names in the CouchDb server. Use symbol - name quotes to specify mixed or lower case field names like so: + with unquoted keyword symbols are normally converted to upper case + by Lisp and this results in upper case field names in the CouchDb + server. Use quotes in symbol names to specify mixed or lower case + field names, like so:
;; Create a document with a mixed case field name. This document ;; will appear in the database as, "MixedCaseName" -(create-document '((:|MixedCaseName| . "Value")) :id "mixed-case1") -(get-document "mixed-case1") -=> ((:|_id| . "mixed-case1") (:|_rev| . "2016717365") (:|MixedCaseName| . "Value")) +(create-document '((:|MixedCaseName| . "Value")) :id "mixed-case") +(get-document "mixed-case") +=> ((:|_id| . "mixed-case") (:|_rev| . "2016717365") (:|MixedCaseName| . "Value"))The native document representation in the CouchDb protocol is - a JSON object. Clouchdb - automatically translates documents between JSON and Lisp - associative lists. + a JSON object. Clouchdb translates + documents to and from JSON as necessary.
@@ -647,11 +650,13 @@
- When a document is created CouchDb assigns special properties to that - document, these properties cannot be modified by clients. The special - properties include the document's ID (:_id) and the document revision - number (:_rev). All special properties begin with an underscore (_) - symbol. + When a document is created CouchDb assigns special properties to + that document, these properties cannot be modified by clients. The + special properties include the document's ID (:|_id|) and the + document revision number (:|_rev|). All special properties begin + with an underscore (_) symbol. CouchDb uses lower case for these + special properties therefore, as of Clouchdb version 0.0.8, they + will always appear as quoted keyword symbols.
@@ -762,12 +767,12 @@ id revision+@@ -786,6 +791,10 @@ (document-property :name (get-document "max")) => "Maxwell Smart"-Delete the specified document, which must include the standard CouchDb -special variables :|_id| and :|_rev|. The document may also identified by -ID. If revision is specified, delete the specific revision of -identified document, otherwise, delete the most current revision by -fetching the document by ID and using its :_rev value for the -deletion. + Delete the specified document, which must include the standard + CouchDb special variables :|_id| and :|_rev|. The document may also + identified by ID. If revision is specified, deletes the specific + revision of identified document. If no revision is specified, + deletes the most current revision by fetching the document by ID and + using its :|_rev| value for the deletion.
+See +(set-document-property) +
[Function]
@@ -844,11 +853,11 @@Create a new document or update an existing one. If the document is -new, the ID must be specified. If the document has been fetched from -the server (and still retains its :_* CouchDb special properties) then -no ID need be specified. If an ID is specified and it differs from the -existing :_id value, then a new document is created with the specified -ID and any non-special properties of the document. +new an ID must be specified. If the document has been fetched from the +server (and still retains its :|_*| CouchDb special properties) then +no ID need be specified. If an parameter ID is provided and it differs +from the :|_id| value in the document, then a new document is created +with the provided ID and any non-special properties of the document.
Example: @@ -871,19 +880,21 @@
- This function can be used to easily extract data from complex - documents or other CouchDb data such as results returned from - queries. The query parameter is a list containing zero or more query - expressions to match in the specified document. + This function can be used to extract data from complex documents or + other CouchDb data such as results returned from views. The query + parameter is a list containing zero or more query expressions. A + query expression can be either a keyword symbol, which simply + matches the keyword field name in the document, wild card symbols, + or a function.
--
Query Operator Values ++
@@ -910,31 +924,29 @@ Examples:Query Operators Type Description - Symbol +keyword symbol Matches field name in document @@ -899,10 +910,13 @@ function - Invokes function with a single parameter, which is the value of - the previous match or the document if the function is the first - element in the query list. The return value of function is - applied to any subsequent query parameters. + The function should accept a single parameter, which will + contain the value of the previous match or the initial document + if the function is the first element in the query list. Query + operators following the function are applied to the result of + the function or, if the function is the last operator in the + query, the function return value is collected in the + query-document results list. -;; Get all values for :agent under :agents -(query-document '(:agents :agent) - '((:agents - (((:name . "Max") (:agent . 86)) - ((:name . "Ninety Nine") (:agent . 99)) - ((:name . "Fang") (:agent "K-9")))))) -=> (("K-9") 99 86) - -;; Get names of agents that work for Control or Kaos, where those agents have names -(query-document '(:* :name) - '(((:control-agents +;; Secret Agent document to query +(setf *agents* '((:control (((:name . "Max") (:agent . 86)) ((:name . "Ninety Nine") (:agent . 99)) ((:agent . 44)) ((:agent . 13)) ((:name . "Hymie")) ((:name . "Larrabee")) - ((:name . "Fang") (:agent "K-9"))))) - ((:kaos-agents - (((:name . "Siegfried")) - ((:name . "Shtarker")) - ((:name . "The Claw")) - ((:name . "Colonel vol Klaus"))))))) - -=> ("Colonel vol Klaus" "The Claw" "Shtarker" "Siegfried" "Fang" "Larrabee" "Hymie" "Ninety Nine" "Max") + ((:name . "Fang") (:agent . "K-9")))) + (:kaos + (((:name . "Siegfried")) + ((:name . "Shtarker")) + ((:name . "The Claw")) + ((:name . "Colonel von Klaus")))))) + +;; Get the agent values for all Control agents that have these values +(query-document '(:control :agent) *agents*) +=> ("K-9" 13 44 99 86) + +;; Get names of agents that work for Control or Kaos, for agents who have names +(query-document '(:* :name) *agents*) +=> ("Colonel von Klaus" "The Claw" "Shtarker" "Siegfried" "Fang" "Larrabee" + "Hymie" "Ninety Nine" "Max") ;; Get a value from a deeply nested position (query-document '(:** :value) '((:a . @@ -950,18 +962,23 @@ ((:very . ((:deeply . ((:nested . - ((:value . "Deep Value 1"))))))))) + ((:value . "Deep Value"))))))))) (:this . ((:value . ((:is . - ((:different . "Deep Value 2"))))))))) + ((:different . "Different Deep Value"))))))))) -=> (((:IS (:DIFFERENT . "Deep Value 2"))) "Deep Value 1") +=> (((:IS (:DIFFERENT . "Different Deep Value"))) "Deep Value") -;; Use the clouchdb function (get-document) -;; to look up documents by ID as found by the previous query element, -;; :|id|. The form below will return the value for :name for all -;; documents in the current database that have one or more :name properties +;; Query using a function +;; +;; Query the results of (get-all-documents), extracting all +;; document :|id| values in the :|rows| property. +;; +;; Use the clouchdb function (get-document) to look up the +;; corresponding document for each value of :|id|. The form below will +;; return the value of the :name property for all documents in the +;; current database that have one or more :name properties (query-document `(:|rows| :|id| ,#'get-document :** :name) (get-all-documents)) @@ -975,9 +992,12 @@ set-document-property doc &rest args-Modify or add property values to a document. This function returns a -new copy of the specified document, it does not modify its -parameter. Be sure to use the return value. +Modify existing named property or add property names and values to a +document. This function returns a new copy of the specified document, +it does not modify its document parameter. +
++Example:
(create-document '((:name . "Maxwell Smart") (:agent . 86)) :id "max") @@ -985,7 +1005,7 @@ (document-property :name (get-document "max")) => "Maxwell Smart" -;; Modify :name and add :employer properties +;; Modify existing :name value and add :employer property (put-document (set-document-property (get-document "max") :name "Maxwell Smart, Secret Agent" @@ -1275,7 +1295,7 @@ -Back to Common-lisp.net.
+Back to Common-lisp.net.
Valid XHTML 1.0 Strict From peddy at common-lisp.net Fri Feb 22 01:33:50 2008 From: peddy at common-lisp.net (peddy) Date: Thu, 21 Feb 2008 20:33:50 -0500 (EST) Subject: [clouchdb-cvs] CVS clouchdb/src Message-ID: <20080222013350.053CB5B074@common-lisp.net> Update of /project/clouchdb/cvsroot/clouchdb/src In directory clnet:/tmp/cvs-serv26656 Modified Files: clouchdb.lisp Log Message: Use document-to-json to quote view key parameters to support complex types --- /project/clouchdb/cvsroot/clouchdb/src/clouchdb.lisp 2008/02/16 19:36:07 1.21 +++ /project/clouchdb/cvsroot/clouchdb/src/clouchdb.lisp 2008/02/22 01:33:49 1.22 @@ -66,11 +66,11 @@ "Return \"false\" if value is nil, otherwise nil" (unless value "false")) -(defvar *view-options* - '((:key . ((:name . "key") (:fn . doublequote))) - (:start-key . ((:name . "startkey") (:fn . doublequote))) - (:start-key-docid . ((:name . "startkey_docid") (:fn . doublequote))) - (:end-key . ((:name . "endkey") (:fn . doublequote))) +(defparameter *view-options* + `((:key . ((:name . "key") (:fn . document-to-json))) + (:start-key . ((:name . "startkey") (:fn . document-to-json))) + (:start-key-docid . ((:name . "startkey_docid") (:fn . document-to-json))) + (:end-key . ((:name . "endkey") (:fn . document-to-json))) (:count . ((:name . "count") (:fn . value-as-string))) (:update . ((:name . "update") (:fn . false-if-false))) (:descending . ((:name . "descending") (:fn . true-if-true))) @@ -333,32 +333,33 @@ document or null." (let ((res)) (labels ((q (query doc rec) -;; (format t "~%test: r=~s, query=~s doc=~s~%" rec query doc) + ;;(format t "~%test: r=~s, query=~s doc=~s~%" rec query doc) (cond ((null doc) nil) ((null query) (push doc res)) ((eq :** (car query)) +;; (format t "action: :**~%") (q (cdr query) doc t)) ((and (listp query) (eq :** (car query))) -;; (format t "action: :**~%") +;; (format t "action: (:**)~%") (q (cdr query) doc t)) ((assoclp doc) -;; (format t "action: assoclp doc=~s ~%" doc) + ;; (format t "action: assoclp doc=~s ~%" doc) (dolist (e doc) (q query e rec))) ((functionp (car query)) -;; (format t "action: functionp~%") + ;; (format t "action: functionp~%") (q (cdr query) (funcall (car query) doc) rec)) ((keyword-assocp doc) -;; (format t "action: keyword-assocp doc=~S~%" doc) + ;; (format t "action: keyword-assocp doc=~S~%" doc) (cond ((or (eq (car query) (car doc)) (eq :* (car query))) -;; (format t "action: keyword asscoc=t~%" doc) + ;; (format t "action: keyword asscoc=t~%" doc) (q (cdr query) (cdr doc) nil)) ((and rec (listp (cdr doc))) (q query (cdr doc) t)))) ((listp doc) -;; (format t "action: listp~%") + ;; (format t "action: listp~%") (dolist (e doc) (q query e rec))) (t nil)))) @@ -376,7 +377,7 @@ (multiple-value-bind (body status headers uri stream must-close reason-phrase) (apply #'drakma:http-request (make-uri uri) args) (declare (ignore reason-phrase stream uri headers status)) -;; (format t " -> uri: ~S~%" uri) +;; (format t " -> uri: ~a~%" uri) ;; (format t " -> headers: ~S~%" headers) (cond (must-close ;; (format t "body: ~S~%" body)