I would like to know if you are interested in aligning database open modes (:mode on Sqlite3.open, Connection and start_link) with sqlite3_open_v2 instead.
As of now, Exqlite.Sqlite3.open and Exqlite.Connection and Exqlite.start_link map to :mode in a way that mirrors legacy sqlite3_open function (read/write + create bundled), not the finer-grained sqlite3_open_v2 flags.
I'd be happy to implement a change if there's interest; this issue is only to align on direction.
Current behavior
:mode defaults to :readwrite, which sets SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE.
|
|
|
defp do_flags_from_mode([:readwrite | tail], acc), |
|
do: do_flags_from_mode(tail, [:sqlite_open_readwrite, :sqlite_open_create | acc]) |
:readonly exists and requires the file to exist.
Connection.connect always calls mkdir_p on the parent directory before Sqlite3.open/2. -
|
defp do_connect(database, options) do |
|
with {:ok, directory} <- resolve_directory(database), |
|
:ok <- mkdir_p(directory), |
|
{:ok, db} <- Sqlite3.open(database, options), |
I can see the comment here, but not sure of the reason. I'm asking wheter that should stay unconditional. SQLite does not do this even with URI mode=rwc. -
|
# SQLITE_OPEN_CREATE will create the DB file if not existing, but |
|
# will not create intermediary directories if they are missing. |
|
# So let's preemptively create the intermediate directories here |
|
# before trying to open the DB file. |
- The project is compiled with
SQLITE_USE_URI=1 (Makefile), so URI paths like file:path/to/db?mode=rw / mode=rwc / mode=ro can work, but this is not documented on Connection and is easy to miss when using :mode keywords.
Possible Approaches
Option A - Align :readwrite with SQLite (breaking)
| Mode |
Flags |
:readwrite |
READWRITE only |
:readwrite_create |
READWRITE | CREATE |
Option B - Adding a new mode (non-breaking)
Keep :readwrite (READWRITE \| CREATE).
Add a new mode, e.g. :readwrite_only or :readwrite_existing for READWRITE without CREATE.
mkdir_p
Should parent-directory creation remain unconditional on Connection, or become opt-in (e.g. ensure_path: true) for callers who want strict SQLite semantics?
Motivation
I went down this path because of kino_db SQLite smart cell in Livebook. I gave it a typo'd path and it silently created a new empty database instead of erroring, which then showed up as a confusing "no such table." I was expecting a wrong path failure instead of it fabricating the state - I was also not able to test it by setting the modes because it doesn't have a selector for it except for using the URI syntax. However, that is another topic for kino_db maintainers.
Questions
- Is aligning with
sqlite3_open_v2 flag semantics a goal this library would pursue?
- Preference for Option A vs Option B?
- Should
mkdir_p be part of the same change or handled separately?
- Any concerns for downstream users? (I'm thinking ecto_sqlite3)
I might be missing context, happy to adjust based on feedback.
I would like to know if you are interested in aligning database open modes (
:modeonSqlite3.open,Connectionandstart_link) with sqlite3_open_v2 instead.As of now,
Exqlite.Sqlite3.openandExqlite.ConnectionandExqlite.start_linkmap to:modein a way that mirrors legacysqlite3_openfunction (read/write + create bundled), not the finer-grainedsqlite3_open_v2flags.I'd be happy to implement a change if there's interest; this issue is only to align on direction.
Current behavior
:modedefaults to:readwrite, which setsSQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE.exqlite/lib/exqlite/sqlite3.ex
Lines 62 to 64 in 3e45199
:readonlyexists and requires the file to exist.Connection.connectalways callsmkdir_pon the parent directory beforeSqlite3.open/2. -exqlite/lib/exqlite/connection.ex
Lines 580 to 583 in 3e45199
I can see the comment here, but not sure of the reason. I'm asking wheter that should stay unconditional. SQLite does not do this even with URI
mode=rwc. -exqlite/lib/exqlite/connection.ex
Lines 771 to 774 in 3e45199
SQLITE_USE_URI=1(Makefile), so URI paths likefile:path/to/db?mode=rw/mode=rwc/mode=rocan work, but this is not documented onConnectionand is easy to miss when using:modekeywords.Possible Approaches
Option A - Align
:readwritewith SQLite (breaking):readwriteREADWRITEonly:readwrite_createREADWRITE | CREATEOption B - Adding a new mode (non-breaking)
Keep
:readwrite(READWRITE \| CREATE).Add a new mode, e.g.
:readwrite_onlyor:readwrite_existingforREADWRITEwithoutCREATE.mkdir_pShould parent-directory creation remain unconditional on
Connection, or become opt-in (e.g.ensure_path: true) for callers who want strict SQLite semantics?Motivation
I went down this path because of kino_db SQLite smart cell in Livebook. I gave it a typo'd path and it silently created a new empty database instead of erroring, which then showed up as a confusing "no such table." I was expecting a wrong path failure instead of it fabricating the state - I was also not able to test it by setting the modes because it doesn't have a selector for it except for using the URI syntax. However, that is another topic for kino_db maintainers.
Questions
sqlite3_open_v2flag semantics a goal this library would pursue?mkdir_pbe part of the same change or handled separately?I might be missing context, happy to adjust based on feedback.