1 ;;; BongoDB, an embedded document-based engine
2 ;;; Copyright (C) 2016 by Javier Sancho Fernandez <jsf at jsancho dot org>
4 ;;; This program is free software: you can redistribute it and/or modify
5 ;;; it under the terms of the GNU General Public License as published by
6 ;;; the Free Software Foundation, either version 3 of the License, or
7 ;;; (at your option) any later version.
9 ;;; This program is distributed in the hope that it will be useful,
10 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
11 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 ;;; GNU General Public License for more details.
14 ;;; You should have received a copy of the GNU General Public License
15 ;;; along with this program. If not, see <http://www.gnu.org/licenses/>.
18 (define-module (bongodb)
19 #:use-module (ice-9 receive)
20 #:use-module (ice-9 vlist)
21 #:use-module (srfi srfi-9)
22 #:use-module (srfi srfi-9 gnu)
23 #:export (make-collection
33 ;;; Collection Definition
35 (define-record-type collection
36 (make-collection-record table)
40 (define (make-collection)
41 (make-collection-record vlist-null))
44 (vlist-length (get-table col)))
46 (set-record-type-printer! collection
49 "#<collection with ~a documents>"
53 ;;; Working with documents
55 (define (format-document document)
56 "Return a vhash document ready to store in a collection"
58 (cond ((vhash? document)
61 (alist->vhash document)))))
63 (define (document-with-id document)
64 "Return always a document with an id"
65 (or (and (vhash-assoc '_id document)
67 (vhash-cons '_id (gensym) document)))
69 (define (insert col . documents)
70 "Insert documents into the collection and return the new collection"
71 (cond ((null? documents)
74 (let* ((document (format-document (car documents)))
75 (docid (cdr (vhash-assoc '_id document)))
76 (newcol (make-collection-record (vhash-cons docid document (get-table col)))))
77 (receive (rescol docids)
78 (apply insert (cons newcol (cdr documents)))
79 (values rescol (cons docid docids)))))))
81 (define (find col . filter)
82 "Query the collection and return the documents that match with filter"
83 (let ((table (get-table col)))
85 (lambda (key document result)
86 (cond ((match-document? document filter)
87 (cons (vhash->alist document) result))
93 (define (match-document? document filter)
94 "Try to match the given document with a list of conditions"
99 ((car filter) document)
100 (match-document? document (cdr filter))))))
105 (define ($eq field value)
107 (let ((stored (vhash-assoc field document)))
109 (equal? (cdr stored) value)))))
112 (define ($exists field)
114 (and (vhash-assoc field document)
120 (not (expr document))))
125 (define (vhash->alist vhash)
127 (lambda (key value result) (assoc-set! result key value))