Skip to content

Instantly share code, notes, and snippets.

@mpapierski
Created December 23, 2016 10:16
Show Gist options
  • Save mpapierski/84473b982f60a612a049927777b142ce to your computer and use it in GitHub Desktop.
Save mpapierski/84473b982f60a612a049927777b142ce to your computer and use it in GitHub Desktop.
#include <iostream>
#include <string>
#include <system_error>
#include "sqlite3.h"
#include "git2.h"
struct sqlite_error_category
: std::error_category
{
const char *name() const noexcept override
{
return "sqlite3";
}
std::string message(int rc) const override
{
return ::sqlite3_errstr(rc);
}
};
int git_module_xCreate(sqlite3 *, void *pAux,
int argc, const char * const *argv,
sqlite3_vtab **ppVTab,
char **pzErr)
{
std::cout << "xCreate (";
for (int i = 0; i < argc; i++) {
std::cout << argv[i] << " ";
}
std::cout << ")" << std::endl;
git_repository* repo = nullptr;
std::cout << "Init git repository: " << argv[argc - 1] << std::endl;
int err;
if ((err = git_repository_open(&repo, argv[argc - 1])) < 0) {
std::cerr << giterr_last() << std::endl;
return SQLITE_FAIL;
}
std::cout << repo << std::endl;
return SQLITE_OK;
}
int git_module_xConnect(sqlite3 *, void *pAux,
int argc, const char * const *argv,
sqlite3_vtab **ppVTab,
char **pzErr)
{
std::cout << "xConnect" << std::endl;
return SQLITE_OK;
}
int git_module_xBestIndex(sqlite3_vtab *pVTab, sqlite3_index_info *)
{
std::cout << "xBestIndex" << std::endl;
return SQLITE_OK;
}
int git_module_xDisconnect(sqlite3_vtab *pVTab)
{
std::cout << "xDisconnect" << std::endl;
return SQLITE_OK;
}
int git_module_xDestroy(sqlite3_vtab *pVTab)
{
std::cout << "xDestroy" << std::endl;
return SQLITE_OK;
}
int git_module_xOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor)
{
std::cout << "xOpen" << std::endl;
return SQLITE_OK;
}
int git_module_xClose(sqlite3_vtab_cursor *)
{
std::cout << "xClose" << std::endl;
return SQLITE_OK;
}
int git_module_xFilter(sqlite3_vtab_cursor *, int idxNum, const char *idxStr,
int argc, sqlite3_value **argv)
{
std::cout << "xFilter" << std::endl;
return SQLITE_OK;
}
int git_module_xNext(sqlite3_vtab_cursor *)
{
std::cout << "xNext" << std::endl;
return SQLITE_OK;
}
int git_module_xEof(sqlite3_vtab_cursor *)
{
std::cout << "xEof" << std::endl;
return SQLITE_OK;
}
int git_module_xColumn(sqlite3_vtab_cursor *, sqlite3_context *, int)
{
std::cout << "xColumn" << std::endl;
return SQLITE_OK;
}
int git_module_xRowid(sqlite3_vtab_cursor *, sqlite_int64 *pRowid)
{
std::cout << "xRowid" << std::endl;
return SQLITE_OK;
}
int git_module_xUpdate(sqlite3_vtab *, int, sqlite3_value **, sqlite_int64 *)
{
std::cout << "xUpdate" << std::endl;
return SQLITE_OK;
}
int git_module_xBegin(sqlite3_vtab *pVTab)
{
std::cout << "xBegin" << std::endl;
return SQLITE_OK;
}
int git_module_xSync(sqlite3_vtab *pVTab)
{
std::cout << "xSync" << std::endl;
return SQLITE_OK;
}
int git_module_xCommit(sqlite3_vtab *pVTab)
{
std::cout << "xCommit" << std::endl;
return SQLITE_OK;
}
int git_module_xRollback(sqlite3_vtab *pVTab)
{
std::cout << "xRollback" << std::endl;
return SQLITE_OK;
}
int git_module_xFindFunction(sqlite3_vtab *pVtab, int nArg, const char *zName,
void (**pxFunc)(sqlite3_context *, int, sqlite3_value **),
void **ppArg)
{
std::cout << "xFindFunction" << std::endl;
return SQLITE_OK;
}
int git_module_xRename(sqlite3_vtab *pVtab, const char *zNew)
{
std::cout << "Rename" << std::endl;
return SQLITE_OK;
}
/* The methods above are in version 1 of the sqlite_module object. Those
** below are for version 2 and greater. */
int git_module_xSavepoint(sqlite3_vtab *pVTab, int)
{
std::cout << "xSavepoint" << std::endl;
return SQLITE_OK;
}
int git_module_xRelease(sqlite3_vtab *pVTab, int)
{
std::cout << "xRelease" << std::endl;
return SQLITE_OK;
}
int git_module_xRollbackTo(sqlite3_vtab *pVTab, int)
{
std::cout << "xRollbackTo" << std::endl;
return SQLITE_OK;
}
void Init_git_module(sqlite3_module *mod)
{
std::cout << "sqlite3_module" << std::endl;
mod->iVersion = 1;
mod->xCreate = git_module_xCreate;
mod->xConnect = git_module_xConnect;
mod->xBestIndex = git_module_xBestIndex;
mod->xDisconnect = git_module_xDisconnect;
mod->xDestroy = git_module_xDestroy;
mod->xOpen = git_module_xOpen;
mod->xClose = git_module_xClose;
mod->xFilter = git_module_xFilter;
mod->xNext = git_module_xNext;
mod->xEof = git_module_xEof;
mod->xColumn = git_module_xColumn;
mod->xRowid = git_module_xRowid;
mod->xUpdate = git_module_xUpdate;
mod->xBegin = git_module_xBegin;
mod->xSync = git_module_xSync;
mod->xCommit = git_module_xCommit;
mod->xRollback = git_module_xRollback;
mod->xFindFunction = git_module_xFindFunction;
mod->xRename = git_module_xRename;
mod->xSavepoint = git_module_xSavepoint;
mod->xRelease = git_module_xRelease;
mod->xRollbackTo = git_module_xRollbackTo;
}
void Clean_git_module(void *ptr)
{
std::cout << "Clean git module " << ptr << std::endl;
}
int main(int argc, char* argv[]) try
{
if (argc < 2) {
std::cerr << argv[0] << " [git repo" << std::endl;
return 1;
}
int rc;
sqlite3 *db = nullptr;
if ((rc = sqlite3_open(":memory:", &db)) != SQLITE_OK)
{
throw std::system_error(rc, sqlite_error_category(), "sqlite3_open");
}
sqlite3_module git_module = {};
Init_git_module(&git_module);
if ((rc = sqlite3_create_module_v2(
db, /* SQLite connection to register module with */
"git", /* Name of the module */
&git_module, /* Methods for the module */
nullptr, /* Client data for xCreate/xConnect */
Clean_git_module)) != SQLITE_OK)
{
throw std::system_error(rc, sqlite_error_category(), "sqlite3_create_module_v2");
}
char *err = nullptr;
char *query = sqlite3_mprintf("CREATE VIRTUAL TABLE commits USING git('%q')", argv[1]);
std::cout << query << std::endl;
if ((rc = sqlite3_exec(db, query, nullptr, nullptr, &err)) != SQLITE_OK)
{
std::cerr << err << std::endl;
throw std::system_error(rc, sqlite_error_category(), "sqlite3_exec");
}
sqlite3_close(db);
}
catch (std::exception &e)
{
std::cerr << e.what() << std::endl;
return 1;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment