【问题标题】:Building and maintaining a database in Emacs?在 Emacs 中构建和维护数据库?
【发布时间】:2009-10-26 06:22:04
【问题描述】:

我正在阅读 Peter Siebel 的书 Practical Common LispSimple Database 部分,想法是维护一个包含大约 50,000 条记录的小型数据库。我认为在 Emacs 中执行此操作可能是一个有趣且有用的练习。除了少数notable differences 之外,Emacs Lisp 在某种程度上与 CL 兼容。上述示例中使用的 format 函数是一个主要区别。

这里的代码包含在 CL 中构建、保存和加载数据库所需的一切。这可以修改为在 Emacs 中正常工作吗?我省略了 selectwhere 函数,但我想包括它们。也许有更好的 Emacs 构建和维护数据库的方法?就个人而言,我将其用作学习 CL 和解决现有问题的练习。

;;简单的 Common Lisp 数据库 ;; http://www.gigamonkeys.com/book/practical-a-simple-database.html ;; (defvar *db* 无) (defun make-cd(标题艺术家评级被撕毁) (列表:标题标题:艺术家艺术家:评级等级:撕开撕开)) (defun add-record (cd) (push cd *db*)) (defun转储-db() (dolist (cd *db*) (格式 t"~{~a:~10t~a~%~}~%" cd))) (defun save-db (文件名) (with-open-file (out 文件名 :方向:输出 :if-exists :supersede) (使用标准 io 语法 (打印 *db* 输出)))) (defun load-db (文件名) (with-open-file(在文件名中) (使用标准 io 语法 (setf *db* (读入))))) ; === ; ;添加一些记录 ; (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)) ; (转储数据库) ; (保存数据库“cd.db”) ; (加载数据库“cd.db”)

【问题讨论】:

    标签: emacs elisp


    【解决方案1】:

    这是我的解决方案:

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

    【讨论】:

      【解决方案2】:

      当我尝试为 Emacs 编写电子书库时,我将记录存储在一个列表中,不时将其保存到磁盘中。当列表长度超过约五千条记录时,性能受到影响。

      以下是代码中的一些函数:

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

      【讨论】:

      • 能否包含一个示例数据库文件?您的命令不是交互式的。你如何调用它们?
      • 我提取了 (with-temp-buffer ...) 部分并使用了它。
      猜你喜欢
      • 1970-01-01
      • 2010-10-18
      • 1970-01-01
      • 2015-12-08
      • 2017-01-30
      • 2011-07-17
      • 2016-09-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多