From 4740ec95b9715b4df93223c8547ac2ea398d0201 Mon Sep 17 00:00:00 2001 From: Javier Sancho Date: Sat, 23 Jan 2016 07:08:45 +0100 Subject: [PATCH] GNU Guile prototype --- src/bongodb.scm | 96 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 src/bongodb.scm diff --git a/src/bongodb.scm b/src/bongodb.scm new file mode 100644 index 0000000..c6b2571 --- /dev/null +++ b/src/bongodb.scm @@ -0,0 +1,96 @@ +;;; +;;; BongoDB, an embedded document-based engine +;;; Copyright (C) 2016 by Javier Sancho Fernandez +;;; +;;; This program is free software: you can redistribute it and/or modify +;;; it under the terms of the GNU General Public License as published by +;;; the Free Software Foundation, either version 3 of the License, or +;;; (at your option) any later version. +;;; +;;; This program is distributed in the hope that it will be useful, +;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;; GNU General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with this program. If not, see . + + +(define-module (bongodb) + #:use-module (ice-9 receive) + #:use-module (ice-9 vlist) + #:use-module (srfi srfi-9) + #:use-module (srfi srfi-9 gnu)) + + +;;; Collection Definition + +(define-record-type collection + (make-collection-record table) + collection? + (table get-table)) + +(define (make-collection) + (make-collection-record vlist-null)) + +(set-record-type-printer! collection + (lambda (record port) + (format port + "#" + (vlist-length (get-table record))))) + + +;;; Working with documents + +(define (format-document document) + "Return a vhash document ready to store in a collection" + (document-with-id + (cond ((vhash? document) + document) + (else + (alist->vhash document))))) + +(define (document-with-id document) + "Return always a document with an id" + (or (and (vhash-assoc '_id document) + document) + (vhash-cons '_id (gensym) document))) + +(define (insert col . documents) + "Insert documents into the collection and return the new collection" + (cond ((null? documents) + (values col '())) + (else + (let* ((document (format-document (car documents))) + (docid (cdr (vhash-assoc '_id document))) + (newcol (make-collection-record (vhash-cons docid document (get-table col))))) + (receive (rescol docids) + (apply insert (cons newcol (cdr documents))) + (values rescol (cons docid docids))))))) + +(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)) + '() + table))) + + +;;; Tools + +(define (vhash->alist vhash) + (vhash-fold-right + (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)))))) -- 2.39.2