在Emacs中构建和维护数据库?

7 emacs elisp

我正在阅读Peter Siebel的书" Practical Common Lisp"简单数据库部分,其中包括维护一个大约50,000条记录的小型数据库.我认为在Emacs中这样做可能是一个有趣且有用的练习.除了一些值得注意的差异之外,Emacs Lisp在某种程度上与CL兼容.上例中使用的格式函数是一个主要区别.

这是包含在CL中构建,保存和加载数据库所需的所有内容的代码.这可以修改为在Emacs中运行良好吗?我省略了selectwhere函数,但是我想要包含它们.也许有更好的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"))
Run Code Online (Sandbox Code Playgroud)