In one of my last customer projects, I used SQLite
for data storage. SQLite is a SQL database library written in C.
With SQLite, one does not need to install a DBMS like Postgres or MySQL.
For some types of applications, this is exactly what's needed.
With Go, SQLite is used through a mechanism
cgo. That is, when Go encounters C code, it invokes
gcc for compiling that code and including it in the resulting binary.
To make a long story short, I like SQLite a lot, but the way it has to be
used in Go ... Well, it sucks!
For cgo, I had to jump through hoops to make it work: Finding a suitable gcc was a long path of heavy trial-and-error. Even then, cgo slowed down my build cycle considerably (I think linking was the time-consuming part). Then, everytime I wanted to release a test version for the customer, I had to spin up a Linux machine, copy the source over, compile, test, and copy the resulting binary back to my Windows dev machine. In short: It was a drag. I whished I could somehow get rid of that SQLite C-Code compile-time dependency and have a SQLite runtime dependency instead.
I came up with Sqinn-Go that does exactly that: Get rid of the SQLite C-Code and access SQLite database by some other means. Since calling DLLs/Shared Object Libs does not work in Go (at least not in a cross-platform way), I thought about the ultimate plugin mechanism: Have a subprocess, and communicate with that process via stdin/stdout. The main process (my app) sends SQL statements to the Sqinn subprocess. The Sqinn subprocess then invokes the SQLite library and sends results back to its stdout, from where it can be read by the main process (my app).
As it turned out, it worked. Performance-wise it is comparable to cgo based solutions, in some cases it's faster, in some cases it's slower. It depends. I have published everything on github and have been using it in two more projects. I runs in production on a small web-app.
Check it out on github: