| 94 | } cursor; |
| 95 | |
| 96 | static int |
| 97 | my_open(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor) { |
| 98 | MEMFILE* mf; |
| 99 | CURL* curl; |
| 100 | char* json; |
| 101 | CURLcode res = CURLE_OK; |
| 102 | char error[CURL_ERROR_SIZE] = {0}; |
| 103 | char* cert_file = getenv("SSL_CERT_FILE"); |
| 104 | |
| 105 | mf = memfopen(); |
| 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"); |
| 111 | if (cert_file) |
| 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; |
| 121 | return SQLITE_FAIL; |
| 122 | } |
| 123 | |
| 124 | picojson::value* v = new picojson::value; |
| 125 | std::string err; |
| 126 | picojson::parse(*v, mf->data, mf->data + mf->size, &err); |
| 127 | memfclose(mf); |
| 128 | |
| 129 | if (!err.empty()) { |
| 130 | delete v; |
| 131 | std::cerr << err << std::endl; |
| 132 | return SQLITE_FAIL; |
| 133 | } |
| 134 | |
| 135 | cursor *c = (cursor *)sqlite3_malloc(sizeof(cursor)); |
| 136 | c->rows = v; |
| 137 | c->index = 0; |
| 138 | *ppCursor = &c->base; |
| 139 | return SQLITE_OK; |
| 140 | } |
| 141 | |
| 142 | static int |
| 143 | my_close(cursor *c) { |