-;;;
;;; BongoDB, an embedded document-based engine
;;; Copyright (C) 2016 by Javier Sancho Fernandez <jsf at jsancho dot org>
;;;
#: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
+ $eq
+ $exists
+ $not))
;;; Collection Definition
(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
"#<collection with ~a documents>"
- (vlist-length (get-table record)))))
+ (count record))))
;;; Working with documents
(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"
(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 (vhash->alist document) result))
+ (else
+ result)))
'()
table)))
+(define (match-document? document filter)
+ "Try to match the given document with a list of conditions"
+ (cond ((null? filter)
+ #t)
+ (else
+ (and
+ ((car filter) document)
+ (match-document? document (cdr filter))))))
+
+
+;;; 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))))
+
+
;;; Tools
(define (vhash->alist vhash)
(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))))))