2009-10-26 11 views
6

Peter Siebelの本Practical Common LispSimple Databaseのセクションを読んで、約50,000レコードの小さなデータベースを維持する考えでした。私はEmacsでこれをやっているのが面白くて便利な運動かもしれないと思いました。 Emacs Lispはいくつかの例外を除いてCLと幾分互換性があります。notable differences上記の例で使用されているの形式関数は大きな違いの1つです。Emacsでのデータベースの構築と維持?

ここには、CLでデータベースを構築、保存、ロードするために必要なすべてのコードが含まれています。 Emacsでうまく動作するように修正できますか?私はを選択しましたここではが機能しますが、それらを含めることをお勧めします。 Emacsによるデータベースの構築と保守の方が優れているのでしょうか?個人的に、私はCLを学び、既存の問題を解決するための練習としてこれを使用しています。

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

答えて

2

私はEmacs用の電子ブックライブラリを作成しようとしたとき、そのレコードをリストに格納して、時折ディスクに保存しました。リストの長さが約5000レコードを超えると、パフォーマンスが低下しました。ここで

は、コードからいくつかの機能です:

(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

あなたはサンプルのDBファイルが含まれてもらえますか?あなたのコマンドはインタラクティブではありません。あなたはそれらをどのように呼びますか? –

+0

(with-temp-buffer ...)セクションを抽出して使用しました。 –

2

は、ここに私のソリューションです:

 

(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* 
 
関連する問題