magit / emacsql

A high-level Emacs Lisp RDBMS front-end
The Unlicense
554 stars 41 forks source link

Can't get past `(invalid-read-syntax "#" 37 73)` #105

Closed agzam closed 1 year ago

agzam commented 1 year ago

Can someone please guide me how to use the package.

I'm trying to query a Browser DB. This is what I'm doing:

(setq db (emacsql-sqlite "/tmp/bhist-brave.sqlite"))

returns emacsql-sqlite-connection:

#s(emacsql-sqlite-connection #<process emacsql-sqlite> nil #<finalizer> "/tmp/bhist-brave.sqlite")

But any attempt to query it:

(emacsql db [:select [title] :from urls])

results in:

(invalid-read-syntax "#" 37 73) Debugger entered--Lisp error: (invalid-read-syntax "#" 37 73) read() #f(compiled-function (connection) "Parse well-formed output into an s-expression." #)(#) apply(#f(compiled-function (connection) "Parse well-formed output into an s-expression." #) # nil) emacsql-parse(#) #f(compiled-function (connection sql &rest args) #)(# [:select [title] :from urls]) apply(#f(compiled-function (connection sql &rest args) #) # [:select [title] :from urls]) emacsql(# [:select [title] :from urls]) (progn (emacsql db [:select [title] :from urls])) eval((progn (emacsql db [:select [title] :from urls])) t) elisp--eval-last-sexp(nil) eval-last-sexp(nil) eros-eval-last-sexp(nil) funcall-interactively(eros-eval-last-sexp nil) call-interactively(eros-eval-last-sexp) (save-excursion (goto-char (plist-get (or (sp-get-enclosing-sexp) (sp-get-expression)) :end)) (call-interactively 'eros-eval-last-sexp)) (let ((evil-move-beyond-eol t)) (save-excursion (goto-char (plist-get (or (sp-get-enclosing-sexp) (sp-get-expression)) :end)) (call-interactively 'eros-eval-last-sexp))) eval-current-form-sp(1) funcall-interactively(eval-current-form-sp 1) call-interactively(eval-current-form-sp nil nil) command-execute(eval-current-form-sp)

I think I need a custom parser or something, but I can't find examples of how to build one.

Also, (emacsql-connection-p db) returns nil. So, maybe something else is wrong?

The same DB works fine in Emacs 29 with (sqlite-open) and (sqlite-select), but I want to make it so the package could be used in prior versions too.

tarsius commented 1 year ago

EmacSQL is not intended to be used as a general-purpose database interface. See https://github.com/magit/emacsql#faq.

agzam commented 1 year ago

I understand that, and I guess my question is a bit general. I wonder if this lib can be (should be) used as a default driver for querying SQL DBs, in my case, specifically sqlite.

The built-in Emacs 29 lib makes querying sqlite a breeze.

What's the recommended/idiomatic way of doing it for previous versions of Emacs?

I'm a bit lost trying to understand how emacsql-sqlite, emacssql-sqlite-builtin, emacssql-sqlite-module are related.

Also, I recently set (setq forge-database-connector 'sqlite-builtin), but got surprised that I still need to install emacsql-sqlite-builtin. I'm using the latest Emacs built from --head, I thought I don't need another package.

Is there a good place to start reading to understand how these packages are related and work with each other?

And again, if someone points to a simple snippet example that queries (any arbitrary) sqlite db in a way that works in both Emacs 29 and older versions - that would be awesome.

agzam commented 1 year ago

I guess, I'm just gonna use sqlite.el

tarsius commented 1 year ago

I understand that, and I guess my question is a bit general. I wonder if this lib can be (should be) used as a default driver for querying SQL DBs, in my case, specifically sqlite.

Every value read from the database is passed through read (except NULL). Unless the database was created using EmacSQL and is only accessed through that, then it is almost certain that read will throw an error for some values. That's the cause of the error in your case.

The built-in Emacs 29 lib makes querying sqlite a breeze.

What's the recommended/idiomatic way of doing it for previous versions of Emacs?

https://github.com/pekingduck/emacs-sqlite3-api works very similar to the new built-in support, which was inspired by the former.

I'm a bit lost trying to understand how emacsql-sqlite, emacssql-sqlite-builtin, emacssql-sqlite-module are related.

Users can choose which backend they want to use, but third-party packages need some boilerplate to actually allow that (see code involving forge-database-connector for an example).

Also, I recently set (setq forge-database-connector 'sqlite-builtin), but got surprised that I still need to install emacsql-sqlite-builtin. I'm using the latest Emacs built from --head, I thought I don't need another package.

By using that setting you are telling EmacSQL that you want to use the backend provided by the emacsql-sqlite-builtin package, which is a thin wrapper around the new built-in support.

For the time being third-party packages still declare that they depend on emacsql-sqlite, which was the only SQLite backend that existed when they added that dependency. Unfortunately package.el/elpa does not allow declaring a dependency such as (or emacsql-sqlite emacssql-sqlite-builtin emacssql-sqlite-module).

In the future all these backends (or just the two new ones) might be put back into the emacsql package to make things easier. Other approaches are also still on the table. I won't work on that until January or maybe February.

Is there a good place to start reading to understand how these packages are related and work with each other?

Beyond what I wrote above, I don't think so. I know there is work to be done here, but until I have decided how to do things going forward, I won't write any documentation that might very soon become obsolete.

And again, if someone points to a simple snippet example that queries (any arbitrary) sqlite db in a way that works in both Emacs 29 and older versions - that would be awesome.

It probably would not be hard to write a small wrapper that abstracts the new built-in support and the very similar api provided by https://github.com/pekingduck/emacs-sqlite3-api.

I guess, I'm just gonna use sqlite.el

A file by that name is part of the new builtin support in Emacs. There also exists a file by the same name in https://gitlab.com/cnngimenez/sqlite.el. To use the latter, you would have to rename it and possibly some functions it defines to remove the conflict.

agzam commented 1 year ago

A few things I kinda guessed (even before you told them), but now it is all clear. Thank you for the detailed explanation.