Created
December 23, 2016 10:16
-
-
Save mpapierski/84473b982f60a612a049927777b142ce to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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