2009-10-26 8 views
6

Ich habe den Simple Database Abschnitt von Peter Siebels Buch Practical Common Lisp mit der Idee gelesen, eine kleine Datenbank von ungefähr 50.000 Aufzeichnungen beizubehalten. Ich dachte, dies in Emacs zu tun, könnte eine interessante und nützliche Übung sein. Emacs Lisp ist etwas kompatibel mit CL bis auf ein paar notable differences. Die Format Funktion, die in dem obigen Beispiel verwendet wird, ist ein Hauptunterschied.Aufbau und Pflege einer Datenbank in Emacs?

Hier ist der Code, der alles enthält, was zum Konstruieren, Speichern und Laden der Datenbank in CL benötigt wird. Kann dies geändert werden, um in Emacs gut zu funktionieren? Ich unterblieb die wählen und wo Funktionen, aber ich möchte sie einbeziehen. Vielleicht gibt es einen besseren Emacs Weg, eine Datenbank aufzubauen und zu pflegen? Persönlich benutze ich dies als Übung, um CL zu lernen und ein bestehendes Problem zu lösen.

 
;; 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") 

Antwort

2

Als ich versuchte, eine E-Book-Bibliothek für Emacs, ich die Datensätze in einer Liste gespeichert zu schreiben, auf der Festplatte von Zeit zu Zeit zu sparen. Wenn die Listenlänge mehr als fünftausend Datensätze überschritten hatte, litt die Leistung.

Hier sind einige Funktionen aus dem Code:

(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

Könnten Sie eine Probe db-Datei enthalten? Ihre Befehle sind nicht interaktiv. Wie rufen Sie sie an? –

+0

Ich habe den Abschnitt (with-temp-buffer ...) extrahiert und verwendet. –

2

Hier ist meine Lösung:

 

(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* 
 
Verwandte Themen