-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Proposal for reading SQLite databases embedded in Go executables #968
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
Comments
Perhaps I'm missing something, but can't you just open the original database file normally in read-only mode? What is driving the desire for using an in-memory database specifically? Also, just FYI, rather than using |
I will assume by "normally" that @rittneje meant not using ":memory:" but just opening the database "from a file" using the standard VFS provided with the build. The problem is that the standard VFS looks to disk sources and not memory sources for the []byte. We'll have to be careful with terminology here but I consider opening and working with an embedded database to be "in memory" just like opening using ":memory:" with the understanding that there are many differences of course. The executable is in memory thus anything embedded in it is in memory, we just need to be able to open it.
As flexible as |
My question is why you are trying to open a database from |
@rittneje - As the proposal states, the goal is to avoid the overhead of opening in ":memory:" mode and then consuming CPU to populate that new, empty database when a copy of an already populated database has been lifted into memory via embedding. Your question seems to explore why the developer made the design choice to embed, and for that I'd say it is beyond the purview of the proposal; we should trust that the correct decision was made. Some common use cases would be embedded website servers with hybrid static/dynamic content and backends for report API's. I think cloud FaaS would specifically benefit from not having the CPU cycles spent on redundant database building on every call. Hope that helps. |
Closing issue. Implementation of this proposal is moving to modernc.org/sqlite |
@GeekStocks did you get anywhere with this either with |
As long as the SQLite implementation references the original C language (in go-sqlite or modernc.org/sqlite both), I don't think it will achieve your goal. Because original SQLite implementation does not handle Go's I/O layer. |
Proposal for reading SQLite databases embedded in Go executables
Purpose
Numerous forums in multiple programming languages are littered with questions similar to this:
The disappointing answer to these questions is simply that the authors of SQLite have not exposed a method to do so. Driver authors / maintainers like @mattn for this package cannot interface to something that doesn't exist. Given this, the "fallback" answer usually wins the day: open SQLite using
":memory:"
mode and thenExec
a SQL script containing a backup "dump" of the database. Once the overhead of this loading process has occurred, the user has the environment they want.But is there a better way that could avoid this loading overhead? The purpose of this proposal is to explore and solicit comments for a proposed custom SQLite VFS module that would work in tandem with
mattn/go-sqlite3
and Go's newembed
package. You are encouraged to comment if you can add to the knowledge presented here and/or see another way to accomplish the goal.Trying a different approach
Most observed approaches to this problem start with the desired
:memory:
mode and quickly run into trouble with no pointer parameter available. This proposal avoids SQLite's memory mode altogether and seeks to use the existing SQLite URI mode to open an embedded database. By virtue of being embedded the database is already in memory and accessable via a variable, so opening it is all that remains.As of Go version 1.16 released in February, 2021 embedding a SQLite database into a Go executable is now trivial:
Go's
embed
package offersstring
,[]byte
, and the newembed.FS
data types as embedded possibilities. Users of the "fallback" solution can now at least embed their SQL script backup "dumps" as a string. Since this author knows no method to load SQLite databases from[]byte
, the focus of this proposal is on the newembed.FS
option shown above.It is important to note that embedding digital assets into Go executables is a read-only process:
This limits the usefulness of this proposal; if a project must have write ability on the SQLite database then the "fallback" method remains the only choice. But as the use cases for read-only databases are legion, we soldier on.
Under the hood SQLite uses a standard Virtual File System (VFS) to interpret the
open
string and locate files. The VFS chosen depends on the OS of course:We are not limited to these bundled VFSes however; we can subclass SQLite's objects to create our own. If appropriate, the majority of the work can even be delegated to the standard VFS to create a shim:
For Your Consideration
The proposed goal is to enable opening an embedded SQLite database from Go's new
embed.FS
type using a URI and a custom VFS. According to RFC 3986, a URI consists of "...a scheme, an authority, a path, a query string, and a fragment."Consider the following code which extends the previous example:
In this line a standard VFS is being used since no VFS
pragma
was specified. Accordingly the "embeddedDatabase" authority string above is interpreted as a folder name, and not as ourembed.FS
variable of the same name. The proposed solution would require the authority string to be interpreted as a Goembed.FS
variable name, and the path string to be the path to follow within theembed.FS
instance. Thus, the proposedOpen
statement would conceivably look like:If you are knowledgeable and so inclined, please answer or comment on the following questions as you see fit:
mattn/go-sqlite3
?Sources
Go
SQLite
The text was updated successfully, but these errors were encountered: