doltliter embeds a C library. Unlike RSQLite, which
vendors sqlite3.c and compiles it unconditionally, this
package has to find a libdoltlite to build against
— and the right way to do that differs by platform. This article
explains what configure does, so that when it picks
something unexpected you know why.
# install.packages("remotes")
remotes::install_github("CathalByrneGit/doltliter")The three strategies
configure tries these in order of cost, and prints which
one it chose.
1. An installed DoltLite (system)
Costs nothing if you already have DoltLite. configure
looks at pkg-config, then DOLTLITE_HOME, then
explicit DOLTLITE_CFLAGS / DOLTLITE_LIBS, then
the usual prefixes (/usr/local, /usr,
/opt/homebrew, /opt/local).
2. A vendored amalgamation (vendor)
DoltLite publishes a single-file amalgamation, the same shape as SQLite’s. Staging it means the package compiles with no network access at install time, which is the form a CRAN submission would take, and pins the DoltLite version exactly.
It costs about a minute of compile time. This is the default on Windows and Intel macOS, for reasons in the next section.
Why Windows and Intel macOS vendor
This is not arbitrary. Checking the actual release artifacts turned up two things the upstream README does not mention:
- A Windows library archive does exist — but it
contains only
libdoltlite.dll, with no static archive and no.lib/.dll.aimport library. There is nothing for Rtools to link against, so a prebuilt library is not usable there. -
No Intel macOS library is published at all.
install.shlistsosx-x64among its targets, but no such asset exists.
On both platforms the amalgamation is the only route that works, so
configure reaches for it first.
Checking what you got
configure finishes by compiling and running a probe that
asserts the engine really is DoltLite’s prolly tree, so a build that
accidentally linked stock SQLite fails at install time rather than at
your first dolt_* call. You can re-check at any point:
library(doltliter)
doltlite_engine() # "prolly" for a DoltLite build
#> [1] "prolly"
doltlite_version() # the bundled SQLite version
#> [1] "3.54.0"dolt_version() needs a connection, and reports the
DoltLite release:
con <- DBI::dbConnect(Doltlite(), tempfile(fileext = ".db"))
dolt_version(con)
#> [1] "v0.50.12"
DBI::dbGetInfo(con)[c("doltlite.engine", "doltlite.version", "branch")]
#> $doltlite.engine
#> [1] "prolly"
#>
#> $doltlite.version
#> [1] "v0.50.12"
#>
#> $branch
#> [1] "main"
DBI::dbDisconnect(con)Two things that will surprise you
An empty dbname is not version
controlled. SQLite’s anonymous temporary database is created in
the original B-tree format, so none of the dolt_*
functions exist there. The package says so plainly rather than letting
SQLite report “no such function”:
tmp <- DBI::dbConnect(Doltlite(), "")
DBI::dbGetQuery(tmp, "SELECT doltlite_engine() AS engine")
#> engine
#> 1 orig
dolt_status(tmp)
#> Error:
#> ! dolt_status() needs a DoltLite-format database, but this connection reports engine 'orig'.
#> Anonymous temporary databases (dbname = "") and attached stock SQLite files are not version controlled; connect to a file path instead.Use a real path — tempfile() is fine — whenever you want
version control.
The installed package is large. Around 19 MB,
because the engine is statically linked into the shared library. That is
inherent to embedding DoltLite, and the same trade RSQLite makes with
sqlite3.c.