2009-10-26 10 views
6

Estaba leyendo la sección Simple Database del libro de Peter Siebel Practical Common Lisp con la idea de mantener una pequeña base de datos de alrededor de 50,000 registros. Pensé que hacer esto en Emacs podría ser un ejercicio interesante y útil. Emacs Lisp es algo compatible con CL excepto por unos pocos notable differences. La función de formato utilizada en el ejemplo anterior es una diferencia importante.Creando y manteniendo una base de datos en Emacs?

Aquí está el código que contiene todo lo necesario para construir, guardar y cargar la base de datos en CL. ¿Se puede modificar esto para que funcione bien en Emacs? Omití el seleccione y donde funciona, pero me gustaría incluirlos. Tal vez hay una mejor forma de Emacs de construir y mantener una base de datos? Personalmente, estoy usando esto como ejercicio para aprender CL y resolver un problema existente.

 
;; Simple Common Lisp database 
;; http://www.gigamonkeys.com/book/practical-a-simple-database.html 
;; 
(defvar *db* nil) 

(defun make-cd (title artist rating ripped) 
    (list :title title :artist artist :rating rating :ripped ripped)) 

(defun add-record (cd) (push cd *db*)) 

(defun dump-db() 
    (dolist (cd *db*) 
    (format t "~{~a:~10t~a~%~}~%" cd))) 

(defun save-db (filename) 
    (with-open-file (out filename 
        :direction :output 
        :if-exists :supersede) 
    (with-standard-io-syntax 
     (print *db* out)))) 

(defun load-db (filename) 
    (with-open-file (in filename) 
    (with-standard-io-syntax 
     (setf *db* (read in))))) 
; === 
; 
; Add some records 
; 
(add-record (make-cd "Roses" "Kathy Mattea" 7 t)) 
(add-record (make-cd "Fly" "Dixie Chicks" 8 t)) 
(add-record (make-cd "Home" "Dixie Chicks" 9 t)) 

; (dump-db) 
; (save-db "cd.db") 
; (load-db "cd.db") 

Respuesta

2

Cuando traté de escribir una biblioteca de libros electrónicos para Emacs, que almacena los registros en una lista, guardarlo en el disco de vez en cuando. Cuando la longitud de la lista superó los cinco mil registros, el rendimiento sufrió.

Estas son algunas de las funciones del código:

(defun bread-library-load-db() 
"Loads the list of books from disk file to the variable bread-library-db" 
     (if (file-exists-p bread-library-file) 
      (with-temp-buffer 
     (insert-file-contents bread-library-file) 
     (setq bread-library-db (read (current-buffer)))) 
     (setq bread-library-db '()))) 

(defun bread-library-add-book (file) 
    "Attempts to get metadata from file, then prompts for 
confirmation (or modification) of these metadata, then adds the 
book to the database and saves it. Intended use: from dired." 
    (if (assoc file bread-library-db) 
     (error "File is already in the database") 
    (progn 
     (let ((metadata (bread-get-metadata file))) 
    (let ((filename (nth 0 metadata)) 
      (author (read-from-minibuffer 
       "Author: " 
       (nth 1 metadata))) 
      (title (read-from-minibuffer 
       "Title: " 
       (nth 2 metadata))) 
      (genre (read-from-minibuffer "Genre: " (nth 3 metadata))) 
      (tags (read-from-minibuffer "Tags (separated and surrounded by colons): " ":")) 
      (desc (nth 4 metadata))) 
     (setq bread-library-db (cons 
        (list filename author title tags "TOREAD" genre nil desc) 
        bread-library-db)))) 
     (bread-library-save-db bread-library-db)))) 

(defun bread-library-save-db (db) 
    "Save the library database to a file." 
    (message "Saving Bread library database...") 
    (with-temp-buffer 
     (insert "; 1.path 2.author 3.title 4.tags 5.state 6.genre 7.priority 8.description") 
     (print db (current-buffer)) 
     (write-file bread-library-file)) 
    (message "Saving Bread library database...done")) 
+0

Podría incluir un archivo db muestra? Tus comandos no son interactivos. ¿Cómo los invocas? –

+0

Extraje la sección (con-temp-buffer ...) y la utilicé. –

2

aquí está mi solución:

 

(defvar *db* nil) 

(setq *db*()) 

(defun make-cd (title artist rating ripped) 
    (list :title title :artist artist :rating rating :ripped ripped)) 

(defun add-record (cd) (push cd *db*)) 

(defun init() 
    (progn 
    (add-record (make-cd "Roses" "Kathy Mattea" 7 t)) 
    (add-record (make-cd "Fly" "Dixie Chicks" 8 t)) 
    (add-record (make-cd "Home" "Dixie Chicks" 9 t)) 
    )) 

(defun save-db (filename) 
    (with-temp-buffer 
    (print *db* (current-buffer)) 
    (write-file filename)) 
    (message "Saving database...done") 
) 

(defun load-db (filename) 
    (with-temp-buffer 
    (insert-file-contents filename) 
     (setq *db* (read (current-buffer))))) 

(defun dump-db() 
    (dolist (cd *db*) 
    (print cd))) 


;; Test in M-x lisp-interaction-mode 
;;(init) 
;;(save-db "cd.db") 
;*db* 
;(add-record (make-cd "Born To Run" "Bruce Springsteen" 10 t)) 
;(add-record (make-cd "The River" "Bruce Springsteen" 10 t)) 
;(add-record (make-cd "Nebraska" "Bruce Springsteen" 10 t)) 
;(add-record (make-cd "Human Touch" "Bruce Springsteen" 10 nil)) 
;;(save-db "cd.db") 
;(setq *db*()) 
;;(load-db "cd.db") 
;*db* 
 
Cuestiones relacionadas