pkg update and first config fix
org-brain not working, add org-roam
This commit is contained in:
11
lisp/emacsql-sqlite/emacsql-sqlite-pkg.el
Normal file
11
lisp/emacsql-sqlite/emacsql-sqlite-pkg.el
Normal file
@@ -0,0 +1,11 @@
|
||||
(define-package "emacsql-sqlite" "20221127.2146" "EmacSQL back-end for SQLite"
|
||||
'((emacs "25.1")
|
||||
(emacsql "3.1.1"))
|
||||
:commit "6b2e65bdf785364cf7c34c31fea5812e1e58c657" :authors
|
||||
'(("Christopher Wellons" . "wellons@nullprogram.com"))
|
||||
:maintainer
|
||||
'("Jonas Bernoulli" . "jonas@bernoul.li")
|
||||
:url "https://github.com/magit/emacsql")
|
||||
;; Local Variables:
|
||||
;; no-byte-compile: t
|
||||
;; End:
|
||||
173
lisp/emacsql-sqlite/emacsql-sqlite.el
Normal file
173
lisp/emacsql-sqlite/emacsql-sqlite.el
Normal file
@@ -0,0 +1,173 @@
|
||||
;;; emacsql-sqlite.el --- EmacSQL back-end for SQLite -*- lexical-binding:t -*-
|
||||
|
||||
;; This is free and unencumbered software released into the public domain.
|
||||
|
||||
;; Author: Christopher Wellons <wellons@nullprogram.com>
|
||||
;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
|
||||
;; Homepage: https://github.com/magit/emacsql
|
||||
|
||||
;; Package-Version: 3.1.1.50-git
|
||||
;; Package-Requires: ((emacs "25.1") (emacsql "3.1.1"))
|
||||
;; SPDX-License-Identifier: Unlicense
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; This package provides the original EmacSQL back-end for SQLite,
|
||||
;; which uses a custom binary for communicating with a SQLite database.
|
||||
|
||||
;; During package installation an attempt is made to compile the binary.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'cl-lib)
|
||||
(require 'cl-generic)
|
||||
(require 'eieio)
|
||||
(require 'emacsql)
|
||||
|
||||
(emacsql-register-reserved emacsql-sqlite-reserved)
|
||||
|
||||
;;; SQLite connection
|
||||
|
||||
(defvar emacsql-sqlite-data-root
|
||||
(file-name-directory (or load-file-name buffer-file-name))
|
||||
"Directory where EmacSQL is installed.")
|
||||
|
||||
(defvar emacsql-sqlite-executable-path
|
||||
(if (memq system-type '(windows-nt cygwin ms-dos))
|
||||
"sqlite/emacsql-sqlite.exe"
|
||||
"sqlite/emacsql-sqlite")
|
||||
"Relative path to emacsql executable.")
|
||||
|
||||
(defvar emacsql-sqlite-executable
|
||||
(expand-file-name emacsql-sqlite-executable-path
|
||||
(if (or (file-writable-p emacsql-sqlite-data-root)
|
||||
(file-exists-p (expand-file-name
|
||||
emacsql-sqlite-executable-path
|
||||
emacsql-sqlite-data-root)))
|
||||
emacsql-sqlite-data-root
|
||||
(expand-file-name
|
||||
(concat "emacsql/" emacsql-version)
|
||||
user-emacs-directory)))
|
||||
"Path to the EmacSQL backend (this is not the sqlite3 shell).")
|
||||
|
||||
(defvar emacsql-sqlite-c-compilers '("cc" "gcc" "clang")
|
||||
"List of names to try when searching for a C compiler.
|
||||
|
||||
Each is queried using `executable-find', so full paths are
|
||||
allowed. Only the first compiler which is successfully found will
|
||||
used.")
|
||||
|
||||
(defclass emacsql-sqlite-connection (emacsql-connection emacsql-protocol-mixin)
|
||||
((file :initarg :file
|
||||
:type (or null string)
|
||||
:documentation "Database file name.")
|
||||
(types :allocation :class
|
||||
:reader emacsql-types
|
||||
:initform '((integer "INTEGER")
|
||||
(float "REAL")
|
||||
(object "TEXT")
|
||||
(nil nil))))
|
||||
(:documentation "A connection to a SQLite database."))
|
||||
|
||||
(cl-defmethod initialize-instance :after
|
||||
((connection emacsql-sqlite-connection) &rest _rest)
|
||||
(emacsql-sqlite-ensure-binary)
|
||||
(let* ((process-connection-type nil) ; use a pipe
|
||||
(coding-system-for-write 'utf-8-auto)
|
||||
(coding-system-for-read 'utf-8-auto)
|
||||
(file (slot-value connection 'file))
|
||||
(buffer (generate-new-buffer " *emacsql-sqlite*"))
|
||||
(fullfile (if file (expand-file-name file) ":memory:"))
|
||||
(process (start-process
|
||||
"emacsql-sqlite" buffer emacsql-sqlite-executable fullfile)))
|
||||
(setf (slot-value connection 'process) process)
|
||||
(setf (process-sentinel process)
|
||||
(lambda (proc _) (kill-buffer (process-buffer proc))))
|
||||
(emacsql-wait connection)
|
||||
(emacsql connection [:pragma (= busy-timeout $s1)]
|
||||
(/ (* emacsql-global-timeout 1000) 2))
|
||||
(emacsql-register connection)))
|
||||
|
||||
(cl-defun emacsql-sqlite (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-connection :file file)))
|
||||
(when debug
|
||||
(emacsql-enable-debugging connection))
|
||||
connection))
|
||||
|
||||
(cl-defmethod emacsql-close ((connection emacsql-sqlite-connection))
|
||||
"Gracefully exits the SQLite subprocess."
|
||||
(let ((process (emacsql-process connection)))
|
||||
(when (process-live-p process)
|
||||
(process-send-eof process))))
|
||||
|
||||
(cl-defmethod emacsql-send-message ((connection emacsql-sqlite-connection) message)
|
||||
(let ((process (emacsql-process connection)))
|
||||
(process-send-string process (format "%d " (string-bytes message)))
|
||||
(process-send-string process message)
|
||||
(process-send-string process "\n")))
|
||||
|
||||
(cl-defmethod emacsql-handle ((_ emacsql-sqlite-connection) errcode errmsg)
|
||||
"Get condition for ERRCODE and ERRMSG provided from SQLite."
|
||||
(pcase-let ((`(,_ ,_ ,signal ,errstr)
|
||||
(assq errcode emacsql-sqlite-error-codes)))
|
||||
(signal (or signal 'emacsql-error)
|
||||
(list errmsg errcode nil errstr))))
|
||||
|
||||
;;; SQLite compilation
|
||||
|
||||
(defun emacsql-sqlite-compile-switches ()
|
||||
"Return the compilation switches from the Makefile under sqlite/."
|
||||
(let ((makefile (expand-file-name "sqlite/Makefile" emacsql-sqlite-data-root))
|
||||
(case-fold-search nil))
|
||||
(with-temp-buffer
|
||||
(insert-file-contents makefile)
|
||||
(goto-char (point-min))
|
||||
(cl-loop while (re-search-forward "-D[A-Z0-9_=]+" nil :no-error)
|
||||
collect (match-string 0)))))
|
||||
|
||||
(defun emacsql-sqlite-compile (&optional o-level async)
|
||||
"Compile the SQLite back-end for EmacSQL, returning non-nil on success.
|
||||
If called with non-nil ASYNC the return value is meaningless."
|
||||
(let* ((cc (cl-loop for option in emacsql-sqlite-c-compilers
|
||||
for path = (executable-find option)
|
||||
if path return it))
|
||||
(src (expand-file-name "sqlite" emacsql-sqlite-data-root))
|
||||
(files (mapcar (lambda (f) (expand-file-name f src))
|
||||
'("sqlite3.c" "emacsql.c")))
|
||||
(cflags (list (format "-I%s" src) (format "-O%d" (or o-level 2))))
|
||||
(ldlibs (cl-case system-type
|
||||
(windows-nt (list))
|
||||
(berkeley-unix (list "-lm"))
|
||||
(otherwise (list "-lm" "-ldl"))))
|
||||
(options (emacsql-sqlite-compile-switches))
|
||||
(output (list "-o" emacsql-sqlite-executable))
|
||||
(arguments (nconc cflags options files ldlibs output)))
|
||||
(cond ((not cc)
|
||||
(prog1 nil
|
||||
(message "Could not find C compiler, skipping SQLite build")))
|
||||
(t (message "Compiling EmacSQL SQLite binary ...")
|
||||
(mkdir (file-name-directory emacsql-sqlite-executable) t)
|
||||
(let ((log (get-buffer-create byte-compile-log-buffer)))
|
||||
(with-current-buffer log
|
||||
(let ((inhibit-read-only t))
|
||||
(insert (mapconcat #'identity (cons cc arguments) " ") "\n")
|
||||
(eql 0 (apply #'call-process cc nil (if async 0 t) t
|
||||
arguments)))))))))
|
||||
|
||||
;;; Ensure the SQLite binary is available
|
||||
|
||||
(defun emacsql-sqlite-ensure-binary ()
|
||||
"Ensure the EmacSQL SQLite binary is available, signaling an error if not."
|
||||
(unless (file-exists-p emacsql-sqlite-executable)
|
||||
;; try compiling at the last minute
|
||||
(unless (ignore-errors (emacsql-sqlite-compile 2))
|
||||
(error "No EmacSQL SQLite binary available, aborting"))))
|
||||
|
||||
(provide 'emacsql-sqlite)
|
||||
|
||||
;;; emacsql-sqlite.el ends here
|
||||
19
lisp/emacsql-sqlite/sqlite/Makefile
Normal file
19
lisp/emacsql-sqlite/sqlite/Makefile
Normal file
@@ -0,0 +1,19 @@
|
||||
-include ../.config.mk
|
||||
|
||||
.POSIX:
|
||||
LDLIBS = -ldl -lm
|
||||
CFLAGS = -O2 -Wall -Wextra -Wno-implicit-fallthrough \
|
||||
-DSQLITE_THREADSAFE=0 \
|
||||
-DSQLITE_DEFAULT_FOREIGN_KEYS=1 \
|
||||
-DSQLITE_ENABLE_FTS5 \
|
||||
-DSQLITE_ENABLE_FTS4 \
|
||||
-DSQLITE_ENABLE_FTS3_PARENTHESIS \
|
||||
-DSQLITE_ENABLE_RTREE \
|
||||
-DSQLITE_ENABLE_JSON1 \
|
||||
-DSQLITE_SOUNDEX
|
||||
|
||||
emacsql-sqlite: emacsql.c sqlite3.c
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ emacsql.c sqlite3.c $(LDLIBS)
|
||||
|
||||
clean:
|
||||
rm -f emacsql-sqlite
|
||||
BIN
lisp/emacsql-sqlite/sqlite/emacsql-sqlite
Executable file
BIN
lisp/emacsql-sqlite/sqlite/emacsql-sqlite
Executable file
Binary file not shown.
183
lisp/emacsql-sqlite/sqlite/emacsql.c
Normal file
183
lisp/emacsql-sqlite/sqlite/emacsql.c
Normal file
@@ -0,0 +1,183 @@
|
||||
/* This is free and unencumbered software released into the public domain. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "sqlite3.h"
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
char* escape(const char *message) {
|
||||
int i, count = 0, length_orig = strlen(message);
|
||||
for (i = 0; i < length_orig; i++) {
|
||||
if (strchr("\"\\", message[i])) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
char *copy = malloc(length_orig + count + 1);
|
||||
char *p = copy;
|
||||
while (*message) {
|
||||
if (strchr("\"\\", *message)) {
|
||||
*p = '\\';
|
||||
p++;
|
||||
}
|
||||
*p = *message;
|
||||
message++;
|
||||
p++;
|
||||
}
|
||||
*p = '\0';
|
||||
return copy;
|
||||
}
|
||||
|
||||
void send_error(int code, const char *message) {
|
||||
char *escaped = escape(message);
|
||||
printf("error %d \"%s\"\n", code, escaped);
|
||||
free(escaped);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
char *buffer;
|
||||
size_t size;
|
||||
} buffer;
|
||||
|
||||
buffer* buffer_create() {
|
||||
buffer *buffer = malloc(sizeof(*buffer));
|
||||
buffer->size = 4096;
|
||||
buffer->buffer = malloc(buffer->size * sizeof(char));
|
||||
return buffer;
|
||||
}
|
||||
|
||||
int buffer_grow(buffer *buffer) {
|
||||
unsigned factor = 2;
|
||||
char *newbuffer = realloc(buffer->buffer, buffer->size * factor);
|
||||
if (newbuffer == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
buffer->buffer = newbuffer;
|
||||
buffer->size *= factor;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int buffer_read(buffer *buffer, size_t count) {
|
||||
while (buffer->size < count + 1) {
|
||||
if (buffer_grow(buffer) == FALSE) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
size_t in = fread((void *) buffer->buffer, 1, count, stdin);
|
||||
buffer->buffer[count] = '\0';
|
||||
return in == count;
|
||||
}
|
||||
|
||||
void buffer_free(buffer *buffer) {
|
||||
free(buffer->buffer);
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
char *file = NULL;
|
||||
if (argc != 2) {
|
||||
fprintf(stderr,
|
||||
"error: require exactly one argument, the DB filename\n");
|
||||
exit(EXIT_FAILURE);
|
||||
} else {
|
||||
file = argv[1];
|
||||
}
|
||||
|
||||
/* On Windows stderr is not always unbuffered. */
|
||||
#if defined(_WIN32) || defined(WIN32) || defined(__MINGW32__)
|
||||
setvbuf(stderr, NULL, _IONBF, 0);
|
||||
#endif
|
||||
|
||||
sqlite3* db = NULL;
|
||||
if (sqlite3_initialize() != SQLITE_OK) {
|
||||
fprintf(stderr, "error: failed to initialize sqlite\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
|
||||
if (sqlite3_open_v2(file, &db, flags, NULL) != SQLITE_OK) {
|
||||
fprintf(stderr, "error: failed to open %s\n", file);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
buffer *input = buffer_create();
|
||||
while (TRUE) {
|
||||
printf("#\n");
|
||||
fflush(stdout);
|
||||
|
||||
/* Gather input from Emacs. */
|
||||
unsigned length;
|
||||
int result = scanf("%u ", &length);
|
||||
if (result == EOF) {
|
||||
break;
|
||||
} else if (result != 1) {
|
||||
send_error(SQLITE_ERROR, "middleware parsing error");
|
||||
break; /* stream out of sync: quit program */
|
||||
}
|
||||
if (!buffer_read(input, length)) {
|
||||
send_error(SQLITE_NOMEM, "middleware out of memory");
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Parse SQL statement. */
|
||||
sqlite3_stmt *stmt = NULL;
|
||||
result = sqlite3_prepare_v2(db, input->buffer, length, &stmt, NULL);
|
||||
if (result != SQLITE_OK) {
|
||||
send_error(sqlite3_errcode(db), sqlite3_errmsg(db));
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Print out rows. */
|
||||
int first = TRUE, ncolumns = sqlite3_column_count(stmt);
|
||||
printf("(");
|
||||
while (sqlite3_step(stmt) == SQLITE_ROW) {
|
||||
if (first) {
|
||||
printf("(");
|
||||
first = FALSE;
|
||||
} else {
|
||||
printf("\n (");
|
||||
}
|
||||
int i;
|
||||
for (i = 0; i < ncolumns; i++) {
|
||||
if (i > 0) {
|
||||
printf(" ");
|
||||
}
|
||||
int type = sqlite3_column_type(stmt, i);
|
||||
switch (type) {
|
||||
case SQLITE_INTEGER:
|
||||
printf("%lld", sqlite3_column_int64(stmt, i));
|
||||
break;
|
||||
case SQLITE_FLOAT:
|
||||
printf("%f", sqlite3_column_double(stmt, i));
|
||||
break;
|
||||
case SQLITE_NULL:
|
||||
printf("nil");
|
||||
break;
|
||||
case SQLITE_TEXT:
|
||||
fwrite(sqlite3_column_text(stmt, i), 1,
|
||||
sqlite3_column_bytes(stmt, i), stdout);
|
||||
break;
|
||||
case SQLITE_BLOB:
|
||||
printf("nil");
|
||||
break;
|
||||
}
|
||||
}
|
||||
printf(")");
|
||||
}
|
||||
printf(")\n");
|
||||
if (sqlite3_finalize(stmt) != SQLITE_OK) {
|
||||
/* Despite any error code, the statement is still freed.
|
||||
* http://stackoverflow.com/a/8391872
|
||||
*/
|
||||
send_error(sqlite3_errcode(db), sqlite3_errmsg(db));
|
||||
} else {
|
||||
printf("success\n");
|
||||
}
|
||||
}
|
||||
buffer_free(input);
|
||||
|
||||
sqlite3_close(db);
|
||||
sqlite3_shutdown();
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
241687
lisp/emacsql-sqlite/sqlite/sqlite3.c
Normal file
241687
lisp/emacsql-sqlite/sqlite/sqlite3.c
Normal file
File diff suppressed because it is too large
Load Diff
12836
lisp/emacsql-sqlite/sqlite/sqlite3.h
Normal file
12836
lisp/emacsql-sqlite/sqlite/sqlite3.h
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user