You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

91 lines
2.9KB

  1. ;;; Database module, serializing kv stores associated with symbols
  2. ;;; to and from s-expressions on file.
  3. (module database (database-set database-get database-save *database* database-load database-remove get-all-objects object-exists? has-property? toggle-flag database-null)
  4. (import scheme)
  5. (import chicken.io)
  6. (import util)
  7. ;; The global database.
  8. (define *database* '())
  9. ;; This has to exist and be exported in order for the test suite
  10. ;; not to trigger warnings.
  11. (define (database-null)
  12. (set! *database* '()))
  13. ;; Set KEY associated with symbol NAME to VALUE.
  14. (define (database-set name key value)
  15. (set! *database* (let loop ((kv *database*))
  16. (if (null? kv)
  17. (list (cons name (list (cons key value))))
  18. (if (equal? name (caar kv))
  19. (cons (cons name (let loop ((kv (cdar kv)))
  20. (if (null? kv)
  21. (list (cons key value))
  22. (if (equal? key (caar kv))
  23. (cons (cons key value) (cdr kv))
  24. (cons (car kv) (loop (cdr kv))))))) (cdr kv))
  25. (cons (car kv) (loop (cdr kv))))))))
  26. ;; Get KEY associated with symbol NAME, returning DEFAULT if it doesn't exist.
  27. (define (database-get name key default)
  28. (let loop ((kv *database*))
  29. (if (null? kv)
  30. default
  31. (if (equal? name (caar kv))
  32. (let loop ((kv (cdar kv)))
  33. (if (null? kv)
  34. default
  35. (if (equal? key (caar kv))
  36. (cdar kv)
  37. (loop (cdr kv)))))
  38. (loop (cdr kv))))))
  39. ;; Save database to a file, in s-expression format.
  40. (define (database-save filename)
  41. (with-output-to-file filename (thunk (write *database*))))
  42. ;; Load database from a file.
  43. (define (database-load filename)
  44. (with-input-from-file filename (thunk (set! *database* (car (read-list))))))
  45. ;; Remove all associations from symbol NAME from database.
  46. (define (database-remove name)
  47. (set! *database* (let loop ((kv *database*))
  48. (if (null? kv)
  49. '()
  50. (if (equal? name (caar kv))
  51. (cdr kv)
  52. (cons (car kv) (loop (cdr kv))))))))
  53. ;; Get a list of all symbols in the database.
  54. (define (get-all-objects)
  55. (map car *database*))
  56. ;; Does a symbol exist in the database, e.g. is there
  57. ;; a symbol that has values associated with it in the database?
  58. (define (object-exists? object)
  59. (list? (member object (get-all-objects))))
  60. ;; Is there a value PROPERTY associated with the symbol OBJECT?
  61. (define (has-property? object property)
  62. (let loop ((kv *database*))
  63. (if (null? kv)
  64. #f
  65. (if (eq? (caar kv) object)
  66. (let loop ((kv (cdar kv)))
  67. (if (null? kv)
  68. #f
  69. (if (eq? (caar kv) property)
  70. #t
  71. (loop (cdr kv)))))
  72. (loop (cdr kv))))))
  73. ;; If OBJECT has a value FLAG that is unset or false, set it to true.
  74. ;; Else set it to false.
  75. (define (toggle-flag object flag)
  76. (if (database-get object flag #f)
  77. (database-set object flag #f)
  78. (database-set object flag #t))))