diff --git a/lisp/emacsql-sqlite-builtin/emacsql-sqlite-builtin-pkg.el b/lisp/emacsql-sqlite-builtin/emacsql-sqlite-builtin-pkg.el deleted file mode 100644 index a28ba0a9..00000000 --- a/lisp/emacsql-sqlite-builtin/emacsql-sqlite-builtin-pkg.el +++ /dev/null @@ -1,9 +0,0 @@ -(define-package "emacsql-sqlite-builtin" "20250220.1155" "EmacSQL back-end for SQLite using builtin support" 'nil :commit "b868ee6bda90022379730432610f040c62882064" :authors - '(("Jonas Bernoulli" . "emacs.emacsql@jonas.bernoulli.dev")) - :maintainers - '(("Jonas Bernoulli" . "emacs.emacsql@jonas.bernoulli.dev")) - :maintainer - '("Jonas Bernoulli" . "emacs.emacsql@jonas.bernoulli.dev")) -;; Local Variables: -;; no-byte-compile: t -;; End: diff --git a/lisp/emacsql-sqlite-builtin/emacsql-sqlite-builtin.el b/lisp/emacsql-sqlite-builtin/emacsql-sqlite-builtin.el deleted file mode 100644 index 15c6020e..00000000 --- a/lisp/emacsql-sqlite-builtin/emacsql-sqlite-builtin.el +++ /dev/null @@ -1,88 +0,0 @@ -;;; emacsql-sqlite-builtin.el --- EmacSQL back-end for SQLite using builtin support -*- lexical-binding:t -*- - -;; This is free and unencumbered software released into the public domain. - -;; Author: Jonas Bernoulli -;; Maintainer: Jonas Bernoulli - -;; SPDX-License-Identifier: Unlicense - -;;; Commentary: - -;; This library provides an EmacSQL back-end for SQLite, which uses -;; the built-in SQLite support in Emacs 29 an later. - -;;; Code: - -(require 'emacsql-sqlite) - -(require 'sqlite nil t) -(declare-function sqlite-open "sqlite") -(declare-function sqlite-select "sqlite") -(declare-function sqlite-close "sqlite") - -(emacsql-register-reserved emacsql-sqlite-reserved) - -(defclass emacsql-sqlite-builtin-connection (emacsql--sqlite-base) () - "A connection to a SQLite database using builtin support.") - -(cl-defmethod initialize-instance :after - ((connection emacsql-sqlite-builtin-connection) &rest _) - (require (quote sqlite)) - (oset connection handle - (sqlite-open (oref connection file))) - (emacsql-sqlite-set-busy-timeout connection) - (emacsql connection [:pragma (= foreign-keys on)]) - (emacsql-register connection)) - -(cl-defun emacsql-sqlite-builtin (file &key debug) - "Open a connected to database stored in FILE. -If FILE is nil use an in-memory database. - -:debug LOG -- When non-nil, log all SQLite commands to a log -buffer. This is for debugging purposes." - (let ((connection (make-instance #'emacsql-sqlite-builtin-connection - :file file))) - (when debug - (emacsql-enable-debugging connection)) - connection)) - -(cl-defmethod emacsql-live-p ((connection emacsql-sqlite-builtin-connection)) - (and (oref connection handle) t)) - -(cl-defmethod emacsql-close ((connection emacsql-sqlite-builtin-connection)) - (sqlite-close (oref connection handle)) - (oset connection handle nil)) - -(cl-defmethod emacsql-send-message - ((connection emacsql-sqlite-builtin-connection) message) - (condition-case err - (let ((headerp emacsql-include-header)) - (mapcar (lambda (row) - (cond - (headerp (setq headerp nil) row) - ((mapcan (lambda (col) - (cond ((null col) (list nil)) - ((equal col "") (list "")) - ((numberp col) (list col)) - ((emacsql-sqlite-read-column col)))) - row)))) - (sqlite-select (oref connection handle) message nil - (and emacsql-include-header 'full)))) - ((sqlite-error sqlite-locked-error) - (if (stringp (cdr err)) - (signal 'emacsql-error (list (cdr err))) - (pcase-let* ((`(,_ ,errstr ,errmsg ,errcode ,ext-errcode) err) - (`(,_ ,_ ,signal ,_) - (assq errcode emacsql-sqlite-error-codes))) - (signal (or signal 'emacsql-error) - (list errmsg errcode ext-errcode errstr))))) - (error - (signal 'emacsql-error (cdr err))))) - -(cl-defmethod emacsql ((connection emacsql-sqlite-builtin-connection) sql &rest args) - (emacsql-send-message connection (apply #'emacsql-compile connection sql args))) - -(provide 'emacsql-sqlite-builtin) - -;;; emacsql-sqlite-builtin.el ends here diff --git a/lisp/emacsql-sqlite/emacsql-sqlite-pkg.el b/lisp/emacsql-sqlite/emacsql-sqlite-pkg.el deleted file mode 100644 index 2a7eefdb..00000000 --- a/lisp/emacsql-sqlite/emacsql-sqlite-pkg.el +++ /dev/null @@ -1,9 +0,0 @@ -(define-package "emacsql-sqlite" "20250301.1637" "Code used by multiple SQLite back-ends" 'nil :commit "f111b0acc79eadeeb3c6c1332d943f11fd6932ff" :authors - '(("Jonas Bernoulli" . "emacs.emacsql@jonas.bernoulli.dev")) - :maintainers - '(("Jonas Bernoulli" . "emacs.emacsql@jonas.bernoulli.dev")) - :maintainer - '("Jonas Bernoulli" . "emacs.emacsql@jonas.bernoulli.dev")) -;; Local Variables: -;; no-byte-compile: t -;; End: diff --git a/lisp/emacsql-sqlite/emacsql-sqlite.el b/lisp/emacsql-sqlite/emacsql-sqlite.el deleted file mode 100644 index b58a1181..00000000 --- a/lisp/emacsql-sqlite/emacsql-sqlite.el +++ /dev/null @@ -1,296 +0,0 @@ -;;; emacsql-sqlite.el --- Code used by multiple SQLite back-ends -*- lexical-binding:t -*- - -;; This is free and unencumbered software released into the public domain. - -;; Author: Jonas Bernoulli -;; Maintainer: Jonas Bernoulli - -;; SPDX-License-Identifier: Unlicense - -;;; Commentary: - -;; This library contains code that is used by multiple SQLite back-ends. - -;;; Code: - -(require 'emacsql) - -;;; Base class - -(defclass emacsql--sqlite-base (emacsql-connection) - ((file :initarg :file - :initform nil - :type (or null string) - :documentation "Database file name.") - (types :allocation :class - :reader emacsql-types - :initform '((integer "INTEGER") - (float "REAL") - (object "TEXT") - (nil nil)))) - :abstract t) - -;;; Constants - -(defconst emacsql-sqlite-reserved - '( ABORT ACTION ADD AFTER ALL ALTER ANALYZE AND AS ASC ATTACH - AUTOINCREMENT BEFORE BEGIN BETWEEN BY CASCADE CASE CAST CHECK - COLLATE COLUMN COMMIT CONFLICT CONSTRAINT CREATE CROSS - CURRENT_DATE CURRENT_TIME CURRENT_TIMESTAMP DATABASE DEFAULT - DEFERRABLE DEFERRED DELETE DESC DETACH DISTINCT DROP EACH ELSE END - ESCAPE EXCEPT EXCLUSIVE EXISTS EXPLAIN FAIL FOR FOREIGN FROM FULL - GLOB GROUP HAVING IF IGNORE IMMEDIATE IN INDEX INDEXED INITIALLY - INNER INSERT INSTEAD INTERSECT INTO IS ISNULL JOIN KEY LEFT LIKE - LIMIT MATCH NATURAL NO NOT NOTNULL NULL OF OFFSET ON OR ORDER - OUTER PLAN PRAGMA PRIMARY QUERY RAISE RECURSIVE REFERENCES REGEXP - REINDEX RELEASE RENAME REPLACE RESTRICT RIGHT ROLLBACK ROW - SAVEPOINT SELECT SET TABLE TEMP TEMPORARY THEN TO TRANSACTION - TRIGGER UNION UNIQUE UPDATE USING VACUUM VALUES VIEW VIRTUAL WHEN - WHERE WITH WITHOUT) - "List of all of SQLite's reserved words. -Also see http://www.sqlite.org/lang_keywords.html.") - -(defconst emacsql-sqlite-error-codes - '((1 SQLITE_ERROR emacsql-error "SQL logic error") - (2 SQLITE_INTERNAL emacsql-internal nil) - (3 SQLITE_PERM emacsql-access "access permission denied") - (4 SQLITE_ABORT emacsql-error "query aborted") - (5 SQLITE_BUSY emacsql-locked "database is locked") - (6 SQLITE_LOCKED emacsql-locked "database table is locked") - (7 SQLITE_NOMEM emacsql-memory "out of memory") - (8 SQLITE_READONLY emacsql-access "attempt to write a readonly database") - (9 SQLITE_INTERRUPT emacsql-error "interrupted") - (10 SQLITE_IOERR emacsql-access "disk I/O error") - (11 SQLITE_CORRUPT emacsql-corruption "database disk image is malformed") - (12 SQLITE_NOTFOUND emacsql-error "unknown operation") - (13 SQLITE_FULL emacsql-access "database or disk is full") - (14 SQLITE_CANTOPEN emacsql-access "unable to open database file") - (15 SQLITE_PROTOCOL emacsql-access "locking protocol") - (16 SQLITE_EMPTY emacsql-corruption nil) - (17 SQLITE_SCHEMA emacsql-error "database schema has changed") - (18 SQLITE_TOOBIG emacsql-error "string or blob too big") - (19 SQLITE_CONSTRAINT emacsql-constraint "constraint failed") - (20 SQLITE_MISMATCH emacsql-error "datatype mismatch") - (21 SQLITE_MISUSE emacsql-error "bad parameter or other API misuse") - (22 SQLITE_NOLFS emacsql-error "large file support is disabled") - (23 SQLITE_AUTH emacsql-access "authorization denied") - (24 SQLITE_FORMAT emacsql-corruption nil) - (25 SQLITE_RANGE emacsql-error "column index out of range") - (26 SQLITE_NOTADB emacsql-corruption "file is not a database") - (27 SQLITE_NOTICE emacsql-warning "notification message") - (28 SQLITE_WARNING emacsql-warning "warning message")) - "Alist mapping SQLite error codes to EmacSQL conditions. -Elements have the form (ERRCODE SYMBOLIC-NAME EMACSQL-ERROR -ERRSTR). Also see https://www.sqlite.org/rescode.html.") - -;;; Variables - -(defvar emacsql-include-header nil - "Whether to include names of columns as an additional row. -Never enable this globally, only let-bind it around calls to `emacsql'. -Currently only supported by `emacsql-sqlite-builtin-connection' and -`emacsql-sqlite-module-connection'.") - -(defvar emacsql-sqlite-busy-timeout 20 - "Seconds to wait when trying to access a table blocked by another process. -See https://www.sqlite.org/c3ref/busy_timeout.html.") - -;;; Utilities - -(defun emacsql-sqlite-connection (variable file &optional setup use-module) - "Return the connection stored in VARIABLE to the database in FILE. - -If the value of VARIABLE is a live database connection, return that. - -Otherwise open a new connection to the database in FILE and store the -connection in VARIABLE, before returning it. If FILE is nil, use an -in-memory database. Always enable support for foreign key constrains. -If optional SETUP is non-nil, it must be a function, which takes the -connection as only argument. This function can be used to initialize -tables, for example. - -If optional USE-MODULE is non-nil, then use the external module even -when Emacs was built with SQLite support. This is intended for testing -purposes." - (or (let ((connection (symbol-value variable))) - (and connection (emacsql-live-p connection) connection)) - (set variable (emacsql-sqlite-open file nil setup use-module)))) - -(defun emacsql-sqlite-open (file &optional debug setup use-module) - "Open a connection to the database stored in FILE using an SQLite back-end. - -Automatically use the best available back-end, as returned by -`emacsql-sqlite-default-connection'. - -If FILE is nil, use an in-memory database. If optional DEBUG is -non-nil, log all SQLite commands to a log buffer, for debugging -purposes. Always enable support for foreign key constrains. - -If optional SETUP is non-nil, it must be a function, which takes the -connection as only argument. This function can be used to initialize -tables, for example. - -If optional USE-MODULE is non-nil, then use the external module even -when Emacs was built with SQLite support. This is intended for testing -purposes." - (when file - (make-directory (file-name-directory file) t)) - (let* ((class (emacsql-sqlite-default-connection use-module)) - (connection (make-instance class :file file))) - (when debug - (emacsql-enable-debugging connection)) - (emacsql connection [:pragma (= foreign-keys on)]) - (when setup - (funcall setup connection)) - connection)) - -(defun emacsql-sqlite-default-connection (&optional use-module) - "Determine and return the best SQLite connection class. - -Signal an error if none of the connection classes can be used. - -If optional USE-MODULE is non-nil, then use the external module even -when Emacs was built with SQLite support. This is intended for testing -purposes." - (or (and (not use-module) - (fboundp 'sqlite-available-p) - (sqlite-available-p) - (require 'emacsql-sqlite-builtin) - 'emacsql-sqlite-builtin-connection) - (and (boundp 'module-file-suffix) - module-file-suffix - (condition-case nil - ;; Failure modes: - ;; 1. `libsqlite' shared library isn't available. - ;; 2. User chooses to not compile `libsqlite'. - ;; 3. `libsqlite' compilation fails. - (and (require 'sqlite3) - (require 'emacsql-sqlite-module) - 'emacsql-sqlite-module-connection) - (error - (display-warning 'emacsql "\ -Since your Emacs does not come with -built-in SQLite support [1], but does support C modules, we can -use an EmacSQL backend that relies on the third-party `sqlite3' -package [2]. - -Please install the `sqlite3' Elisp package using your preferred -Emacs package manager, and install the SQLite shared library -using your distribution's package manager. That package should -be named something like `libsqlite3' [3] and NOT just `sqlite3'. - -The legacy backend, which uses a custom SQLite executable, has -been remove, so we can no longer fall back to that. - -[1]: Supported since Emacs 29.1, provided it was not disabled - with `--without-sqlite3'. -[2]: https://github.com/pekingduck/emacs-sqlite3-api -[3]: On Debian https://packages.debian.org/buster/libsqlite3-0") - ;; The buffer displaying the warning might immediately - ;; be replaced by another buffer, before the user gets - ;; a chance to see it. We cannot have that. - (let (fn) - (setq fn (lambda () - (remove-hook 'post-command-hook fn) - (pop-to-buffer (get-buffer "*Warnings*")))) - (add-hook 'post-command-hook fn)) - nil))) - (error "EmacSQL could not find or compile a back-end"))) - -(defun emacsql-sqlite-set-busy-timeout (connection) - (when emacsql-sqlite-busy-timeout - (emacsql connection [:pragma (= busy-timeout $s1)] - (* emacsql-sqlite-busy-timeout 1000)))) - -(defun emacsql-sqlite-read-column (string) - (let ((value nil) - (beg 0) - (end (length string))) - (while (< beg end) - (let ((v (read-from-string string beg))) - (push (car v) value) - (setq beg (cdr v)))) - (nreverse value))) - -(defun emacsql-sqlite-list-tables (connection) - "Return a list of symbols identifying tables in CONNECTION. -Tables whose names begin with \"sqlite_\", are not included -in the returned value." - (mapcar #'car - (emacsql connection - [:select name - ;; The new name is `sqlite-schema', but this name - ;; is supported by old and new SQLite versions. - ;; See https://www.sqlite.org/schematab.html. - :from sqlite-master - :where (and (= type 'table) - (not-like name "sqlite_%")) - :order-by [(asc name)]]))) - -(defun emacsql-sqlite-dump-database (connection &optional versionp) - "Dump the database specified by CONNECTION to a file. - -The dump file is placed in the same directory as the database -file and its name derives from the name of the database file. -The suffix is replaced with \".sql\" and if optional VERSIONP is -non-nil, then the database version (the `user_version' pragma) -and a timestamp are appended to the file name. - -Dumping is done using the official `sqlite3' binary. If that is -not available and VERSIONP is non-nil, then the database file is -copied instead." - (let* ((version (caar (emacsql connection [:pragma user-version]))) - (db (oref connection file)) - (db (if (symbolp db) (symbol-value db) db)) - (name (file-name-nondirectory db)) - (output (concat (file-name-sans-extension db) - (and versionp - (concat (format "-v%s" version) - (format-time-string "-%Y%m%d-%H%M"))) - ".sql"))) - (cond - ((locate-file "sqlite3" exec-path) - (when (and (file-exists-p output) versionp) - (error "Cannot dump database; %s already exists" output)) - (with-temp-file output - (message "Dumping %s database to %s..." name output) - (unless (zerop (save-excursion - (call-process "sqlite3" nil t nil db ".dump"))) - (error "Failed to dump %s" db)) - (when version - (insert (format "PRAGMA user_version=%s;\n" version))) - ;; The output contains "PRAGMA foreign_keys=OFF;". - ;; Change that to avoid alarming attentive users. - (when (re-search-forward "^PRAGMA foreign_keys=\\(OFF\\);" 1000 t) - (replace-match "ON" t t nil 1)) - (message "Dumping %s database to %s...done" name output))) - (versionp - (setq output (concat (file-name-sans-extension output) ".db")) - (message "Cannot dump database because sqlite3 binary cannot be found") - (when (and (file-exists-p output) versionp) - (error "Cannot copy database; %s already exists" output)) - (message "Copying %s database to %s..." name output) - (copy-file db output) - (message "Copying %s database to %s...done" name output)) - ((error "Cannot dump database; sqlite3 binary isn't available"))))) - -(defun emacsql-sqlite-restore-database (db dump) - "Restore database DB from DUMP. - -DUMP is a file containing SQL statements. DB can be the file -in which the database is to be stored, or it can be a database -connection. In the latter case the current database is first -dumped to a new file and the connection is closed. Then the -database is restored from DUMP. No connection to the new -database is created." - (unless (stringp db) - (emacsql-sqlite-dump-database db t) - (emacsql-close (prog1 db (setq db (oref db file))))) - (with-temp-buffer - (unless (zerop (call-process "sqlite3" nil t nil db - (format ".read %s" dump))) - (error "Failed to read %s: %s" dump (buffer-string))))) - -(provide 'emacsql-sqlite) - -;;; emacsql-sqlite.el ends here