Re: [Ebib-users] searching across multiple real databases
Brought to you by:
joostkremers
From: Joost K. <joo...@fa...> - 2012-08-18 17:28:01
|
hi robbie, > This posting relates to searching across multiple > databases. Unless I have misread the > documentation badly (always a possibility), basic > emacs-based searches and advanced searching > (resulting in virtual databases) are only > possible within the one database. Is this > correct? yup. > I would like to work across six BibTeX files. i once though i'd do that to, so i added the possibility to work with more than one .bib file to ebib. but then i found it more practical to keep all my biblography entries in one file... ;-) anyway, i never thought about searching across more than one file, but it can certainly be useful. > My questions are two-fold: > > * is this functionality needed ? well, *you* need it, so that would be a yes. ;-) > * is this functionality possible ? i don't see why not. the question one needs to ask is what would be the best way to do it? IIUC, you want to create a union db, which is like a virtual db, but which still allows a virtual db to be created from it, right? that would probably be the most straightforward way, and not too difficult to implement. a few comments to your patch: > --- ebib.el.orig 2012-08-18 00:36:40.663700389 +0200 > +++ ebib.el 2012-08-18 04:33:38.433636738 +0200 > @@ -1518,6 +1518,7 @@ > (ebib-key index "&" ebib-virtual-db-and) > (ebib-key index "|" ebib-virtual-db-or) > (ebib-key index "~" ebib-virtual-db-not) > +(ebib-key index "+" ebib-virtual-db-union) > (ebib-key index ";" ebib-prefix-map) > (ebib-key index "a" ebib-add-entry) > (ebib-key index "b" ebib-index-scroll-down) > @@ -1746,13 +1747,16 @@ > (message "%s found! Press `l' to check Ebib log buffer." (nth ebib-log-error '("Warnings" "Errors")))) > (ebib-log 'log "")) > > -(defun ebib-merge-bibtex-file () > +(defun ebib-merge-bibtex-file (bibfile) > "Merges a BibTeX file into the database." > (interactive) > - (unless (edb-virtual ebib-cur-db) > +; (unless (edb-virtual ebib-cur-db) > + (unless nil ; robbie 18-Aug-2012 this will always be true... ;-) > (if (not ebib-cur-db) > (error "No database loaded. Use `o' to open a database") > - (let ((file (read-file-name "File to merge: "))) > + (let ((file bibfile)) ; could well be 'nil' > + (unless file > + (setq file (read-file-name "File to merge: "))) > (setq ebib-log-error nil) ; we haven't found any errors > (ebib-log 'log "%s: Merging file %s" (format-time-string "%d-%b-%Y: %H:%M:%S") (edb-filename ebib-cur-db)) > (with-temp-buffer > @@ -2889,6 +2893,51 @@ > (ebib-log 'message "invoking: %s %s" "find-file" file-full-path) > (find-file file-full-path)))))) > > +; robbie 18-Aug-2012 > +; from 'ebib-virtual-db-and' > +(defun ebib-virtual-db-union (arg) > + "Combine open databased into a single virtual database. > +If the current database is a virtual database already, > +ignore the command." > + (interactive "p") ; cannot think of a reason for this yup... you could get rid of the "p" and of the arg in the defun. > + (ebib-log 'message "creating virtual union database") > + > + (let* ((dbname "union" ) > + (new-db (ebib-create-new-database nil) ) ; create new database, adds to census > + (count 0 )) > + > + (setf (edb-virtual new-db) t) ; mark virtual, 't' also works the union db shouldn't be marked virtual if it should be possible to create a virtual db from it. OTOH, we cannot set edb-virtual to nil, because that would mean the user can add/delete/modify entries in the union db, which is not what you want. (since the most efficient way to populate the union db is to populate edb-database with the same objects that are in the real dbs, i.e., not with copies, modifying an entry in the union db would modify it in the original db, without the latter getting marked modified. that wouldn't be good... ;-) ) so what we'd need to do is mark the union db in some special way, say with the symbol 'union or the string "union" or something as the value of edb-virtual. that would, however, require modifications to ebib-execute-helper, so that the union db is not recognized as a virtual db. > + (setf (edb-filename new-db) nil) > + (setf (edb-name new-db) (concat "V:" dbname)) I wouldn't concat a "V:" to the db's name, just call it "Union". It's not the same thing as a virtual db, after all. :-) > + (setf (edb-modified new-db) nil) > + (setf (edb-make-backup new-db) nil) > + > + ;; loop non-virtual databases > + (dolist (db ebib-databases) > + (ebib-execute-when you don't need ebib-execute-when here, since you're checking inside the loop whether each db is virtual or not. > + ((database) ; for some reason (real-db) did not seem to take presumably because ebib-execute-when (or more precisely, ebib-execute-helper) checks ebib-cur-db, but that variable is set only in the body of ebib-execute-when, after it has performed its checks. (BTW, it's not necessary to set ebib-cur-db in the loop, since that variable basically determines which db is displayed to the user, and here you're just going through them to get their data, not to display them.) > + (setq ebib-cur-db db) ; change focus > + (unless (edb-virtual db) ; skip virtual databases > + (let ((ebib-merge-bibtex-filename (edb-filename ebib-cur-db) )) > + (ebib-merge-bibtex-file ebib-merge-bibtex-filename) since the union db is simply meant as a transitory db, i wouldn't bother with ebib-merge-bibtex-file. it should be sufficient to add the hash table entries of edb-database of each db to the edb-database hash table of the new union db, and after that's done for all dbs, set edb-keys-list, edb-cur-entry and edb-n-entries. > + (incf count) > + (ebib-log 'message "current database %S" ebib-cur-db) > + (ebib-log 'message "current filename %s\n" (prin1-to-string ebib-merge-bibtex-filename)) > + ))))) > + (ebib-log 'message "traversed %d databases\n" count) > + > + ;; file virtual database > + (ebib-fill-entry-buffer) ; fill entry buffer > + (ebib-fill-index-buffer) ; fill index buffer > + )) before you do this, you need to set ebib-cur-db to the new union db. otherwise you'll just display the database that was current before creating the union db. anyway, it should definitely be possible to do what you suggest, and if you hack up some code, i'd definitely be interested in adding it to ebib. best, joost -- Joost Kremers Life has its moments |