diff options
| author | Lars Ingebrigtsen | 2021-12-11 09:02:52 +0100 |
|---|---|---|
| committer | Lars Ingebrigtsen | 2021-12-11 09:02:52 +0100 |
| commit | d727796e1f7d7af71c898a8cd0d263f9cf34992c (patch) | |
| tree | b666af909c34906a2ad873a1f51c0acef695e326 | |
| parent | 5d476a9ed892e390e05eab73e7b57a4b879a1780 (diff) | |
| download | emacs-d727796e1f7d7af71c898a8cd0d263f9cf34992c.tar.gz emacs-d727796e1f7d7af71c898a8cd0d263f9cf34992c.zip | |
Don't leave open cursors when listing sqlite data
* lisp/sqlite-mode.el (sqlite-mode-list-data)
(sqlite--mode--list-data): Don't leave open cursor (because they
block other processes from deleting stuff).
(sqlite-mode-delete): Adjust to new layout.
| -rw-r--r-- | lisp/sqlite-mode.el | 60 |
1 files changed, 28 insertions, 32 deletions
diff --git a/lisp/sqlite-mode.el b/lisp/sqlite-mode.el index 48916b23116..6714f41f6fe 100644 --- a/lisp/sqlite-mode.el +++ b/lisp/sqlite-mode.el | |||
| @@ -36,11 +36,9 @@ | |||
| 36 | :interactive nil | 36 | :interactive nil |
| 37 | (buffer-disable-undo) | 37 | (buffer-disable-undo) |
| 38 | (setq-local buffer-read-only t | 38 | (setq-local buffer-read-only t |
| 39 | truncate-lines t | 39 | truncate-lines t)) |
| 40 | sqlite-mode--statements nil)) | ||
| 41 | 40 | ||
| 42 | (defvar sqlite--db nil) | 41 | (defvar sqlite--db nil) |
| 43 | (defvar sqlite-mode--statements nil) | ||
| 44 | 42 | ||
| 45 | ;;;###autoload | 43 | ;;;###autoload |
| 46 | (defun sqlite-mode-open-file (file) | 44 | (defun sqlite-mode-open-file (file) |
| @@ -138,9 +136,7 @@ | |||
| 138 | (get-text-property (point) 'sqlite--row)))) | 136 | (get-text-property (point) 'sqlite--row)))) |
| 139 | (unless row | 137 | (unless row |
| 140 | (user-error "No table under point")) | 138 | (user-error "No table under point")) |
| 141 | (let ((stmt (sqlite-select sqlite--db | 139 | (let ((inhibit-read-only t)) |
| 142 | (format "select * from %s" (car row)) nil 'set)) | ||
| 143 | (inhibit-read-only t)) | ||
| 144 | (save-excursion | 140 | (save-excursion |
| 145 | (forward-line 1) | 141 | (forward-line 1) |
| 146 | (if (looking-at " ") | 142 | (if (looking-at " ") |
| @@ -148,8 +144,7 @@ | |||
| 148 | (delete-region (point) (if (re-search-forward "^[^ ]" nil t) | 144 | (delete-region (point) (if (re-search-forward "^[^ ]" nil t) |
| 149 | (match-beginning 0) | 145 | (match-beginning 0) |
| 150 | (point-max))) | 146 | (point-max))) |
| 151 | (sqlite--mode--list-data (list stmt (car row))) | 147 | (sqlite--mode--list-data (list (car row) 0))))))) |
| 152 | (push stmt sqlite-mode--statements)))))) | ||
| 153 | 148 | ||
| 154 | (defun sqlite-mode--more-data (stmt) | 149 | (defun sqlite-mode--more-data (stmt) |
| 155 | (let ((inhibit-read-only t)) | 150 | (let ((inhibit-read-only t)) |
| @@ -158,16 +153,30 @@ | |||
| 158 | (sqlite--mode--list-data stmt))) | 153 | (sqlite--mode--list-data stmt))) |
| 159 | 154 | ||
| 160 | (defun sqlite--mode--list-data (data) | 155 | (defun sqlite--mode--list-data (data) |
| 161 | (let* ((stmt (car data)) | 156 | (let* ((table (car data)) |
| 162 | (table (cadr data)) | 157 | (rowid (cadr data)) |
| 163 | (rows | 158 | stmt) |
| 164 | (cl-loop for i from 0 upto 1000 | 159 | (unwind-protect |
| 165 | for row = (sqlite-next stmt) | 160 | (progn |
| 166 | while row | 161 | (setq stmt |
| 167 | collect row))) | 162 | (sqlite-select |
| 168 | (sqlite-mode--tablify (sqlite-columns stmt) rows (cons 'row table) " ") | 163 | sqlite--db |
| 169 | (when (sqlite-more-p stmt) | 164 | (format "select rowid, * from %s where rowid >= ?" table) |
| 170 | (insert (buttonize " More data...\n" #'sqlite-mode--more-data data))))) | 165 | (list rowid) |
| 166 | 'set)) | ||
| 167 | (sqlite-mode--tablify (sqlite-columns stmt) | ||
| 168 | (cl-loop for i from 0 upto 1000 | ||
| 169 | for row = (sqlite-next stmt) | ||
| 170 | while row | ||
| 171 | do (setq rowid (car row)) | ||
| 172 | collect row) | ||
| 173 | (cons 'row table) | ||
| 174 | " ") | ||
| 175 | (when (sqlite-more-p stmt) | ||
| 176 | (insert (buttonize " More data...\n" #'sqlite-mode--more-data | ||
| 177 | (list table rowid))))) | ||
| 178 | (when stmt | ||
| 179 | (sqlite-finalize stmt))))) | ||
| 171 | 180 | ||
| 172 | (defun sqlite-mode-delete () | 181 | (defun sqlite-mode-delete () |
| 173 | "Delete the row under point." | 182 | "Delete the row under point." |
| @@ -178,19 +187,6 @@ | |||
| 178 | (when (or (not (consp table)) | 187 | (when (or (not (consp table)) |
| 179 | (not (eq (car table) 'row))) | 188 | (not (eq (car table) 'row))) |
| 180 | (user-error "No row under point")) | 189 | (user-error "No row under point")) |
| 181 | ;; We have to remove all open statements before we can delete | ||
| 182 | ;; something. FIXME -- perhaps this should be changed not to use | ||
| 183 | ;; long-lived statements, since this presumably locks the file for | ||
| 184 | ;; other users, too. | ||
| 185 | (dolist (stmt sqlite-mode--statements) | ||
| 186 | (ignore-errors (sqlite-finalize stmt))) | ||
| 187 | (setq sqlite-mode--statements nil) | ||
| 188 | (save-excursion | ||
| 189 | (goto-char (point-min)) | ||
| 190 | (let (match) | ||
| 191 | (while (setq match (text-property-search-forward 'button-data)) | ||
| 192 | (delete-region (prop-match-beginning match) | ||
| 193 | (prop-match-end match))))) | ||
| 194 | (sqlite-execute | 190 | (sqlite-execute |
| 195 | sqlite--db | 191 | sqlite--db |
| 196 | (format "delete from %s where %s" | 192 | (format "delete from %s where %s" |
| @@ -198,7 +194,7 @@ | |||
| 198 | (string-join | 194 | (string-join |
| 199 | (mapcar (lambda (column) | 195 | (mapcar (lambda (column) |
| 200 | (format "%s = ?" (car (split-string column " ")))) | 196 | (format "%s = ?" (car (split-string column " ")))) |
| 201 | (sqlite-mode--column-names (cdr table))) | 197 | (cons "rowid" (sqlite-mode--column-names (cdr table)))) |
| 202 | " and ")) | 198 | " and ")) |
| 203 | row) | 199 | row) |
| 204 | (delete-region (line-beginning-position) (progn (forward-line 1) (point))))) | 200 | (delete-region (line-beginning-position) (progn (forward-line 1) (point))))) |