collection?
count
insert
- find))
+ find
+ update
+ $eq
+ $exists
+ $not
+ $and
+ $set))
;;; Collection Definition
(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)