X-Git-Url: https://git.jsancho.org/?p=bongodb.git;a=blobdiff_plain;f=src%2Fbongodb.scm;h=3e5dc680c115c49e5fa79f00eca1661e9952da90;hp=c6b2571605ba23e3a9b4e1ef64a5796ea57760ba;hb=a5972febd232c4afd64499826c7faab85a10ee03;hpb=4740ec95b9715b4df93223c8547ac2ea398d0201 diff --git a/src/bongodb.scm b/src/bongodb.scm index c6b2571..3e5dc68 100644 --- a/src/bongodb.scm +++ b/src/bongodb.scm @@ -1,4 +1,3 @@ -;;; ;;; BongoDB, an embedded document-based engine ;;; Copyright (C) 2016 by Javier Sancho Fernandez ;;; @@ -20,7 +19,18 @@ #:use-module (ice-9 receive) #:use-module (ice-9 vlist) #:use-module (srfi srfi-9) - #:use-module (srfi srfi-9 gnu)) + #:use-module (srfi srfi-9 gnu) + #:export (make-collection + collection? + count + insert + find + update + $eq + $exists + $not + $and + $set)) ;;; Collection Definition @@ -33,11 +43,14 @@ (define (make-collection) (make-collection-record vlist-null)) +(define (count col) + (vlist-length (get-table col))) + (set-record-type-printer! collection (lambda (record port) (format port "#" - (vlist-length (get-table record))))) + (count record)))) ;;; Working with documents @@ -69,14 +82,73 @@ (values rescol (cons docid docids))))))) (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 value result) (cons (vhash->alist value) result)) + (lambda (key document result) + (cond ((match-document? document filter) + (cons document result)) + (else + result))) '() table))) +(define (match-document? document filter) + "Try to match the given document with a given filter" + (cond ((equal? filter #t) + #t) + (else + (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 +(define ($eq field value) + (lambda (document) + (let ((stored (vhash-assoc field document))) + (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 (define (vhash->alist vhash) @@ -84,13 +156,3 @@ (lambda (key value result) (assoc-set! result key value)) '() vhash)) - - -;;; Testing - -(define (sample-test) - (let ((col (make-collection))) - (format #t "1 New collection: ~a~%" col) - (set! col (insert col '((a . 1) (b . 2)) '((a . 10) (b . 20)) '((a . 1) (b . "hello world")))) - (format #t "2 Insert 3 documents: ~a~%" col) - (format #t "3 Search (a . 1): ~a~%" (find col '((a . 1))))))