Question

Je lisais la section base de données simple de Peter Siebel. livre Practic Common Lisp avec l’idée de maintenir une petite base de données d’environ 50 000 enregistrements. Je pensais que faire cela dans Emacs pourrait être un exercice intéressant et utile. Emacs Lisp est quelque peu compatible avec CL sauf quelques différences notables . La fonction format utilisée dans l'exemple ci-dessus constitue une différence majeure.

Voici le code qui contient tout le nécessaire pour construire, enregistrer et charger la base de données dans CL. Cela peut-il être modifié pour fonctionner correctement dans Emacs? J'ai omis les sélections et les fonctions , mais j'aimerais les inclure. Peut-être y at-il une meilleure façon pour Emacs de créer et de gérer une base de données? Personnellement, je me sers de cet exercice pour apprendre le langage courant et résoudre un problème existant.

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

Était-ce utile?

La solution

Lorsque j'ai essayé d'écrire une bibliothèque de livres électroniques pour Emacs, j'ai stocké les enregistrements dans une liste, en l'enregistrant de temps en temps sur le disque. Lorsque la longueur de la liste dépassait environ cinq mille enregistrements, les performances en souffraient.

Voici quelques fonctions du 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"))

Autres conseils

Voici ma solution:


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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top