-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add loadext plugin #3226
Add loadext plugin #3226
Conversation
Awesome!! Thanks for getting this started! Here are a few thoughts on your questions:
|
I've just realised that connections in beets are per-thread, which opens up an issue of the extension being loaded on one thread but not another. Would we be alright iterating through all of the open connections and loading the extension for all of them? |
Aha; I didn't realize connections were per thread! Maybe the right thing to do, then, would be for the |
Yeah that makes sense to me. sqlite3 itself doesn't do a connection per thread, but it seems our code is doing it instead. Lines 885 to 896 in 0f8a748
|
039df7c
to
e76652c
Compare
It's true—the reason we do that is that SQLite doesn't allow connections to be shared across threads. See the docs for the check_same_threads option for some more details. Anyway, this looks awesome!! Seems like this should totally work. 😃 |
bdb52c4
to
efed541
Compare
Just to put another spanner in the works (see the footnotes). Oddly enough it's enabled on the versions of Python 2 and 3 I have installed from Homebrew on macOS, as well as on Python 2 and 3 I have installed from My thoughts are now as follows:
What do you think @sampsyo? |
Wow; that's really too bad! So close, and yet so far. All three of your proposals sound right to me. I think it's fine for |
c9bf4d3
to
08ffa01
Compare
Alright I think this is ready for a final review now 😁 I'm not exactly great with documentation, so any feedback there is greatly appreciated! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very nice!! Here are just a few documentation suggestions.
docs/plugins/loadext.rst
Outdated
===================== | ||
|
||
Beets uses an SQLite database to store and query library information, which | ||
has support for extensions to extend its functionality. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe an additional sentence here:
The
loadext
plugin lets you enable these SQLite extensions for beets.
docs/plugins/loadext.rst
Outdated
------------- | ||
|
||
To configure the plugin, make a ``loadext`` section in your configuration | ||
file. The section must consist of a list of paths to extensions to load. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I recommend putting the example right here, instead of later down in the last section. You can introduce it by saying something like "The section should look like this:" and list the YAML right there. This makes the introduction mostly self-contained.
docs/plugins/loadext.rst
Outdated
- libicu-dev | ||
- libsqlite3-dev | ||
|
||
The following commands can be then be used to compile the ICU extension: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I recommend a slightly different wording:
Here's roughly how to download, build, and install the extension (although the details might depend on your system):
docs/plugins/loadext.rst
Outdated
$ unzip sqlite-src-3280000.zip | ||
$ cd sqlite-src-3280000/ext/icu | ||
$ gcc -shared -fPIC icu.c `icu-config --ldflags` -o libicu.so | ||
$ cp libicu.so [your beets config directory] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To make this a little more digestible, I'd probably just say:
$ cp libicu.so ~/.config/beets
Readers (advanced ones, anyway) will be able to sort out that they need to think about where to copy the file.
docs/plugins/loadext.rst
Outdated
configuration directory. | ||
|
||
No file extension is required, as SQLite will automatically use the correct | ||
extension for the current platform. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The correct dynamic library extension for the current platform?
Thanks for the feedback on the documentation! I think that's all corrected now 👍 |
Awesome work!! I'll hit the green button now. 😃 🚢 |
Much appreciated! Thanks for all the help regarding the review 👍 |
Note: On Ubuntu 14.04, using libsqlite 3.8.2-1ubuntu2.2, I did a quick one and added #ifndef SQLITE_DETERMINISTIC
#define SQLITE_DETERMINISTIC 0x800
#endif near the top of gcc -shared -fPIC icu.c `icu-config --ldflags` -o libicu.so Afterwards, using loadext, case-insensitive search worked just fine, even on this old system: beet ls -a øye, ärzte
Die Ärzte - 13
Die Ärzte - Ab 18
Die Ärzte - auch
Die Ärzte - Bäst Of
Die Ärzte - Das Beste von kurz nach früher bis jetze
Die Ärzte - Frauen sind Säue Megamix
Die Ärzte - Ist das alles? 13 Höhepunkte mit den Ärzten
Die Ärzte - Jazz ist anders
Die Ärzte - Junge
Die Ärzte - KISS My Ass: Classic KISS Regrooved
Die Ärzte - Rock'n'Roll Realschule
Die Ärzte - Runter mit den Spendierhosen, Unsichtbarer!
Die Ärzte - Satanische Pferde
Erlend Øye - Legao
Die Ärzte - Geräusch beet ls FÖRSTER
Friedel Hensch & Die Cyprys - Die große Schlagerparade der 50er Jahre - Das alte Försterhaus
Otto Waalkes - Der ostfriesische Götterbote - Oberförster Pudlich |
I'm using Pop!_OS and icu-config seems to be deprecated and could not install it, so I have to run like this
|
This is a rough draft at the moment of what a
loadext
plugin could look like for loading SQLite extensions. This plugin can be used to fix #3160 by allowing users to load the ICU plugin like so;Note that this will require the user to compile their own copy of
ext/icu
from SQLite sources.Points of Discussion
I've got a few points of discussion I'd like to bring up regarding this PR;
The elephant in the room;
This is certainly less than ideal, as we're reaching into beets internals from this plugin. There
are twois one possible solutionsI can think of to this;UseThis doesn't work properly, see this thread regarding the issues.SELECT load_extension(...)
load_extension
method todbcore.Database
.Where should these extension paths be relative to? In this initial draft the paths are relative to wherever
beets
is running, and as such running beets in different folders breaks this unless you use an absolute path for the extension. I think using the beets config directory for relative paths is probably the best idea, but I'll leave this open to others to decide.How in depth do we want to go into the documentation with this? This plugin seems like a somewhat advanced feature, as it requires the user to compile their own
ext/icu
extension from the SQLite sources.How do we test this? Do we mock out the
load_extension
method and make sure it's called? Or do we compile the ICU extension on Travis and attempt to call one of the methods provided by it?Compiling the ICU extension
To compile the ICU extension, you need the following;