3 #include <sqlite3-binding.h>
4 #include <sqlite3ext.h>
9 # define EXPORT __declspec(dllexport)
14 SQLITE_EXTENSION_INIT1;
17 char* data; // response data from server
18 size_t size; // response size of data
23 MEMFILE* mf = (MEMFILE*) malloc(sizeof(MEMFILE));
32 memfclose(MEMFILE* mf) {
33 if (mf->data) free(mf->data);
38 memfwrite(char* ptr, size_t size, size_t nmemb, void* stream) {
39 MEMFILE* mf = (MEMFILE*) stream;
40 int block = size * nmemb;
41 if (!mf) return block; // through
43 mf->data = (char*) malloc(block);
45 mf->data = (char*) realloc(mf->data, mf->size + block);
47 memcpy(mf->data + mf->size, ptr, block);
54 memfstrdup(MEMFILE* mf) {
56 if (mf->size == 0) return NULL;
57 buf = (char*) malloc(mf->size + 1);
58 memcpy(buf, mf->data, mf->size);
64 my_connect(sqlite3 *db, void *pAux, int argc, const char * const *argv, sqlite3_vtab **ppVTab, char **c) {
66 ss << "CREATE TABLE " << argv[0]
67 << "(id int, full_name text, description text, html_url text)";
68 int rc = sqlite3_declare_vtab(db, ss.str().c_str());
69 *ppVTab = (sqlite3_vtab *) sqlite3_malloc(sizeof(sqlite3_vtab));
70 memset(*ppVTab, 0, sizeof(sqlite3_vtab));
75 my_create(sqlite3 *db, void *pAux, int argc, const char * const * argv, sqlite3_vtab **ppVTab, char **c) {
76 return my_connect(db, pAux, argc, argv, ppVTab, c);
79 static int my_disconnect(sqlite3_vtab *pVTab) {
85 my_destroy(sqlite3_vtab *pVTab) {
91 sqlite3_vtab_cursor base;
93 picojson::value* rows;
97 my_open(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor) {
101 CURLcode res = CURLE_OK;
102 char error[CURL_ERROR_SIZE] = {0};
103 char* cert_file = getenv("SSL_CERT_FILE");
106 curl = curl_easy_init();
107 curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1);
108 curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2);
109 curl_easy_setopt(curl, CURLOPT_USERAGENT, "curl/7.29.0");
110 curl_easy_setopt(curl, CURLOPT_URL, "https://api.github.com/repositories");
112 curl_easy_setopt(curl, CURLOPT_CAINFO, cert_file);
113 curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
114 curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, error);
115 curl_easy_setopt(curl, CURLOPT_WRITEDATA, mf);
116 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, memfwrite);
117 res = curl_easy_perform(curl);
118 curl_easy_cleanup(curl);
119 if (res != CURLE_OK) {
120 std::cerr << error << std::endl;
124 picojson::value* v = new picojson::value;
126 picojson::parse(*v, mf->data, mf->data + mf->size, &err);
131 std::cerr << err << std::endl;
135 cursor *c = (cursor *)sqlite3_malloc(sizeof(cursor));
138 *ppCursor = &c->base;
143 my_close(cursor *c) {
150 my_filter(cursor *c, int idxNum, const char *idxStr, int argc, sqlite3_value **argv) {
163 return c->index >= c->rows->get<picojson::array>().size() ? 1 : 0;
167 my_column(cursor *c, sqlite3_context *ctxt, int i) {
168 picojson::value v = c->rows->get<picojson::array>()[c->index];
169 picojson::object row = v.get<picojson::object>();
170 const char* p = NULL;
173 p = row["id"].to_str().c_str();
176 p = row["full_name"].to_str().c_str();
179 p = row["description"].to_str().c_str();
182 p = row["html_url"].to_str().c_str();
185 sqlite3_result_text(ctxt, strdup(p), strlen(p), free);
190 my_rowid(cursor *c, sqlite3_int64 *pRowid) {
196 my_bestindex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo) {
200 static const sqlite3_module module = {
208 (int (*)(sqlite3_vtab_cursor *)) my_close,
209 (int (*)(sqlite3_vtab_cursor *, int, char const *, int, sqlite3_value **)) my_filter,
210 (int (*)(sqlite3_vtab_cursor *)) my_next,
211 (int (*)(sqlite3_vtab_cursor *)) my_eof,
212 (int (*)(sqlite3_vtab_cursor *, sqlite3_context *, int)) my_column,
213 (int (*)(sqlite3_vtab_cursor *, sqlite3_int64 *)) my_rowid,
219 NULL, // my_findfunction
224 destructor(void *arg) {
232 sqlite3_extension_init(sqlite3 *db, char **errmsg, const sqlite3_api_routines *api) {
233 SQLITE_EXTENSION_INIT2(api);
234 sqlite3_create_module_v2(db, "github", &module, NULL, destructor);