Greetings,
I have been building a library catalogue application in Gambit-C. It can import CSV, build indexes, and perform searches. It is now time to think about storing this in a file. Does the write function produce output which can be used to recreate the data structures I saved? If yes, how is this done?
So far, the application has a character (command line) interface. If I want a GUI, should I use a binding to an GUI toolkit (e.g. FLTK)? or wrap the application with a Tcl/Tk & Expect front end? If a binding, which one?
Thank you.
Afficher les réponses par date
2009/5/9 Claude Marinier claude-m17@hotmail.com:
Greetings,
I have been building a library catalogue application in Gambit-C. It can import CSV, build indexes, and perform searches. It is now time to think about storing this in a file. Does the write function produce output which can be used to recreate the data structures I saved? If yes, how is this done?
You can dump (serialize) hashtables into a file and read them later. A quick glance at the logs of this ML exhibits what you want:
On 18-May-06, at 10:52 AM, Pouex Machinax wrote: (define table-1 (make-table)) (table-set! table-1 'foo (list 1 2 3 4 5)) (define table-1-ser (object->u8vector table-1)) (define table-2 (u8vector->object table-1-ser))
Just write your serialized object to a file, that should do it.
Or you can (manually) export your data as S-exps and then READ them later.
P!
On 8-May-09, at 3:32 PM, Claude Marinier wrote:
Greetings,
I have been building a library catalogue application in Gambit-C. It can import CSV, build indexes, and perform searches. It is now time to think about storing this in a file. Does the write function produce output which can be used to recreate the data structures I saved? If yes, how is this done?
You can do that using binary serialization (preferred because it is more compact) or textual serialization (useful for debugging because it is somewhat humanly readable). Check the sample code below.
Marc
;; Method #1 (uses binary serialization)
(define (save1 obj filename) (call-with-output-file filename (lambda (p) (let ((v (object->u8vector obj))) (write-subu8vector v 0 (u8vector-length v) p)))))
(define (restore1 filename) (let ((size (file-size filename))) (call-with-input-file filename (lambda (p) (let ((v (make-u8vector size))) (if (not (= size (read-subu8vector v 0 size p))) (error "file size inconsistency") (u8vector->object v)))))))
;; Method #2 (uses textual serialization)
(define (save2 obj filename) (call-with-output-file filename (lambda (p) (output-port-readtable-set! p (readtable-sharing-allowed?-set (output-port-readtable p) 'serialize)) (write obj p))))
(define (restore2 filename) (call-with-input-file filename (lambda (p) (input-port-readtable-set! p (readtable-sharing-allowed?-set (input-port-readtable p) 'serialize)) (read p))))
;; Test by creating a database and saving/restoring it both ways. ;; The database contains cycles. So this test shows that ;; saving/restoring preserves sharing and cycles.
(define-type person id: 99d2e11d-a556-46c6-a468-c4fa546114fc ;; required for serialization name children unprintable: parent)
(define a (make-person "alice" '() #f)) (define b (make-person "bob" '() #f)) (define c (make-person "chuck" (list a b) #f))
(person-parent-set! a c) (person-parent-set! b c)
(define db (list (cons "alice" a) (cons "bob" b) (cons "chuck" c)))
(define (get db key) (cdr (assoc key db)))
;; save/restore using both methods and check that all is well
;; method #1
(save1 db "db1.bin") (define db1 (restore1 "db1.bin"))
(pp (person-children (get db1 "chuck")))
(pp (eq? (person-parent (get db1 "alice")) (get db1 "chuck")))
;; method #2
(save2 db "db2.txt") (define db2 (restore2 "db2.txt"))
(pp (person-children (get db2 "chuck")))
(pp (eq? (person-parent (get db2 "alice")) (get db2 "chuck")))
;; output: ;; ;; (#<person #2 name: "alice" children: ()> ;; #<person #3 name: "bob" children: ()>) ;; #t ;; (#<person #4 name: "alice" children: ()> ;; #<person #5 name: "bob" children: ()>) ;; #t
On 8-May-09, at 3:32 PM, Claude Marinier wrote:
So far, the application has a character (command line) interface. If I want a GUI, should I use a binding to an GUI toolkit (e.g. FLTK)? or wrap the application with a Tcl/Tk & Expect front end? If a binding, which one?
For a Gambit Tcl/Tk binding, check the directory examples/tcltk in the Gambit distribution. You can run the examples from Ousterhout's Tcl/ Tk book with
gsi fig16-1
in that directory after having first done a "make tcltk.o1".
Marc