]> git.jsancho.org Git - bongodb.git/blobdiff - src/bongodb.scm
Advanced queries support
[bongodb.git] / src / bongodb.scm
index c6b2571605ba23e3a9b4e1ef64a5796ea57760ba..6fc16fe0fcfababa251b2e7686263640e2a2cd18 100644 (file)
@@ -1,4 +1,3 @@
-;;;
 ;;; 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))))))