From a5972febd232c4afd64499826c7faab85a10ee03 Mon Sep 17 00:00:00 2001 From: Javier Sancho Date: Fri, 18 Mar 2016 17:39:32 +0100 Subject: [PATCH] Writing support --- src/bongodb.scm | 49 ++++++++++++++++++++++++++++++++++++++---------- tests/sample.scm | 10 +++++++--- 2 files changed, 46 insertions(+), 13 deletions(-) diff --git a/src/bongodb.scm b/src/bongodb.scm index 6fc16fe..3e5dc68 100644 --- a/src/bongodb.scm +++ b/src/bongodb.scm @@ -25,9 +25,12 @@ count insert find + update $eq $exists - $not)) + $not + $and + $set)) ;;; Collection Definition @@ -78,26 +81,40 @@ (apply insert (cons newcol (cdr documents))) (values rescol (cons docid docids))))))) -(define (find col . filter) +(define (find col filter) + "Query the collection and return the documents that match with filter" + (map vhash->alist (inner-find col filter))) + +(define (inner-find col filter) "Query the collection and return the documents that match with filter" (let ((table (get-table col))) (vhash-fold (lambda (key document result) (cond ((match-document? document filter) - (cons (vhash->alist document) result)) + (cons document result)) (else result))) '() table))) (define (match-document? document filter) - "Try to match the given document with a list of conditions" - (cond ((null? filter) + "Try to match the given document with a given filter" + (cond ((equal? filter #t) #t) (else - (and - ((car filter) document) - (match-document? document (cdr filter)))))) + (filter document)))) + +(define (update col filter . changes) + "Update selected documents using the given filter" + (let ((documents (inner-find col filter))) + (apply insert (cons col (map (lambda (doc) (update-document doc changes)) documents))))) + +(define (update-document document changes) + "Update a document with the appropiate changes" + (cond ((null? changes) + document) + (else + (update-document ((car changes) document) (cdr changes))))) ;;; Queries @@ -108,17 +125,29 @@ (and stored (equal? (cdr stored) value))))) - (define ($exists field) (lambda (document) (and (vhash-assoc field document) #t))) - (define ($not expr) (lambda (document) (not (expr document)))) +(define-syntax $and + (syntax-rules () + ((_ expr ...) + (lambda (document) + (and (expr document) + ...))))) + + +;;; Updates + +(define ($set field value) + (lambda (document) + (vhash-cons field value document))) + ;;; Tools diff --git a/tests/sample.scm b/tests/sample.scm index 5054ffe..bd2cc6e 100644 --- a/tests/sample.scm +++ b/tests/sample.scm @@ -32,12 +32,16 @@ (test-eqv 3 (count col)) ; Search -(test-eqv 3 (length (find col))) +(test-eqv 3 (length (find col #t))) (test-eqv 2 (length (find col ($eq 'a 1)))) -(test-eqv 1 (length (find col ($eq 'a 1) ($eq 'b 2)))) -(test-eqv 0 (length (find col ($eq 'a "test")))) +(test-eqv 1 (length (find col ($and ($eq 'a 1) ($eq 'b 2))))) +(test-eqv 0 (length (find col ($eq 'c "test")))) (test-eqv 2 (length (find col ($exists 'b)))) (test-eqv 2 (length (find col ($not ($exists 'c))))) +; Update +(set! col (update col ($exists 'c) ($set 'c "test"))) +(test-eqv 1 (length (find col ($eq 'c "test")))) + (test-end "bongodb") -- 2.39.2