static PyObject * Connection_server_nodes(pycbc_Connection *self, void *unused) { const char * const *cnodes; const char **curnode; PyObject *ret_list; cnodes = lcb_get_server_list(self->instance); if (!cnodes) { PYCBC_EXC_WRAP(PYCBC_EXC_INTERNAL, 0, "Can't get server nodes"); return NULL; } ret_list = PyList_New(0); if (!ret_list) { return NULL; } for (curnode = (const char**)cnodes; *curnode; curnode++) { PyObject *tmpstr = pycbc_SimpleStringZ(*curnode); PyList_Append(ret_list, tmpstr); Py_DECREF(tmpstr); } (void)unused; return ret_list; }
static void get_headers(pycbc_HttpResult *htres, const lcb_http_resp_t * resp) { const char * const *p; PyObject *hval; if (!htres->headers) { return; } if (PyDict_Size(htres->headers)) { return; } if (!resp->v.v0.headers) { return; } for (p = resp->v.v0.headers; *p; p += 2) { hval = pycbc_SimpleStringZ(p[1]); PyDict_SetItemString(htres->headers, p[0], hval); Py_DECREF(hval); } }
static void finalize_data(pycbc_HttpResult *htres) { PyObject *sep; PyObject *res; if (htres->format != PYCBC_FMT_JSON && htres->format != PYCBC_FMT_UTF8) { return; } if (!PyObject_IsTrue(htres->http_data)) { return; } sep = pycbc_SimpleStringZ(""); res = PyUnicode_Join(sep, htres->http_data); Py_DECREF(sep); /* Set the bytes */ Py_DECREF(htres->http_data); htres->http_data = res; if (htres->format == PYCBC_FMT_JSON) { PyObject *args = Py_BuildValue("(O)", htres->http_data); pycbc_assert(PyErr_Occurred() == NULL); res = PyObject_CallObject(pycbc_helpers.json_decode, args); if (res) { Py_XDECREF(htres->http_data); htres->http_data = res; } else { PyErr_Clear(); } Py_XDECREF(args); } }
static int Connection__init__(pycbc_Connection *self, PyObject *args, PyObject *kwargs) { int rv; int conntype = LCB_TYPE_BUCKET; lcb_error_t err; char *conncache = NULL; PyObject *unlock_gil_O = NULL; PyObject *iops_O = NULL; PyObject *timeout = NULL; PyObject *dfl_fmt = NULL; PyObject *tc = NULL; struct lcb_create_st create_opts = { 0 }; struct lcb_cached_config_st cached_config = { { 0 } }; /** * This xmacro enumerates the constructor keywords, targets, and types. * This was converted into an xmacro to ease the process of adding or * removing various parameters. */ #define XCTOR_ARGS(X) \ X("_errors", &self->errors, "O") \ X("_flags", &self->flags, "I") \ X("bucket", &create_opts.v.v1.bucket, "z") \ X("username", &create_opts.v.v1.user, "z") \ X("password", &create_opts.v.v1.passwd, "z") \ X("host", &create_opts.v.v1.host, "z") \ X("conncache", &conncache, "z") \ X("quiet", &self->quiet, "I") \ X("unlock_gil", &unlock_gil_O, "O") \ X("transcoder", &tc, "O") \ X("timeout", &timeout, "O") \ X("default_format", &dfl_fmt, "O") \ X("lockmode", &self->lockmode, "i") \ X("_conntype", &conntype, "i") \ X("_iops", &iops_O, "O") static char *kwlist[] = { #define X(s, target, type) s, XCTOR_ARGS(X) #undef X NULL }; #define X(s, target, type) type static char *argspec = "|" XCTOR_ARGS(X); #undef X if (self->init_called) { PyErr_SetString(PyExc_RuntimeError, "__init__ was already called"); return -1; } self->init_called = 1; self->flags = 0; self->unlock_gil = 1; self->lockmode = PYCBC_LOCKMODE_EXC; #define X(s, target, type) target, rv = PyArg_ParseTupleAndKeywords(args, kwargs, argspec, kwlist, XCTOR_ARGS(X) NULL); #undef X if (!rv) { PYCBC_EXCTHROW_ARGS(); return -1; } if (unlock_gil_O && PyObject_IsTrue(unlock_gil_O) == 0) { self->unlock_gil = 0; } if (create_opts.v.v1.bucket) { self->bucket = pycbc_SimpleStringZ(create_opts.v.v1.bucket); } create_opts.version = 1; create_opts.v.v1.type = conntype; if (iops_O && iops_O != Py_None) { self->iops = pycbc_iops_new(self, iops_O); create_opts.v.v1.io = self->iops; self->unlock_gil = 0; } Py_INCREF(self->errors); if (dfl_fmt == Py_None || dfl_fmt == NULL) { /** Set to 0 if None or NULL */ dfl_fmt = pycbc_IntFromL(0); } else { Py_INCREF(dfl_fmt); /* later decref */ } rv = Connection_set_format(self, dfl_fmt, NULL); Py_XDECREF(dfl_fmt); if (rv == -1) { return rv; } /** Set the transcoder */ if (tc && Connection_set_transcoder(self, tc, NULL) == -1) { return -1; } #ifdef WITH_THREAD if (!self->unlock_gil) { self->lockmode = PYCBC_LOCKMODE_NONE; } if (self->lockmode != PYCBC_LOCKMODE_NONE) { self->lock = PyThread_allocate_lock(); } #endif if (conncache) { if (conntype != LCB_TYPE_BUCKET) { PYCBC_EXC_WRAP(PYCBC_EXC_ARGUMENTS, 0, "Cannot use connection cache with " "management connection"); return -1; } cached_config.cachefile = conncache; memcpy(&cached_config.createopt, &create_opts, sizeof(create_opts)); err = lcb_create_compat(LCB_CACHED_CONFIG, &cached_config, &self->instance, NULL); } else { err = lcb_create(&self->instance, &create_opts); } if (err != LCB_SUCCESS) { self->instance = NULL; PYCBC_EXC_WRAP(PYCBC_EXC_LCBERR, err, "Couldn't create instance. Either bad " "credentials/hosts/bucket names were " "passed, or there was an internal error in creating the " "object"); return -1; } pycbc_callbacks_init(self->instance); lcb_set_cookie(self->instance, self); if (timeout && timeout != Py_None) { if (Connection_set_timeout(self, timeout, NULL) == -1) { return -1; } } PYCBC_CONN_THR_BEGIN(self); err = lcb_connect(self->instance); PYCBC_CONN_THR_END(self); if (err != LCB_SUCCESS) { PYCBC_EXC_WRAP(PYCBC_EXC_LCBERR, err, "Couldn't schedule connection. This might be a result of " "an invalid hostname."); return -1; } err = pycbc_oputil_wait_common(self); if (err != LCB_SUCCESS) { PYCBC_EXCTHROW_WAIT(err); return -1; } return 0; }
static int Bucket__init__(pycbc_Bucket *self, PyObject *args, PyObject *kwargs) { int rv; int conntype = LCB_TYPE_BUCKET; lcb_error_t err; PyObject *unlock_gil_O = NULL; PyObject *iops_O = NULL; PyObject *dfl_fmt = NULL; PyObject *tc = NULL; struct lcb_create_st create_opts = { 0 }; /** * This xmacro enumerates the constructor keywords, targets, and types. * This was converted into an xmacro to ease the process of adding or * removing various parameters. */ #define XCTOR_ARGS(X) \ X("connection_string", &create_opts.v.v3.connstr, "z") \ X("connstr", &create_opts.v.v3.connstr, "z") \ X("username", &create_opts.v.v3.username, "z") \ X("password", &create_opts.v.v3.passwd, "z") \ X("quiet", &self->quiet, "I") \ X("unlock_gil", &unlock_gil_O, "O") \ X("transcoder", &tc, "O") \ X("default_format", &dfl_fmt, "O") \ X("lockmode", &self->lockmode, "i") \ X("_flags", &self->flags, "I") \ X("_conntype", &conntype, "i") \ X("_iops", &iops_O, "O") static char *kwlist[] = { #define X(s, target, type) s, XCTOR_ARGS(X) #undef X NULL }; #define X(s, target, type) type static char *argspec = "|" XCTOR_ARGS(X); #undef X if (self->init_called) { PyErr_SetString(PyExc_RuntimeError, "__init__ was already called"); return -1; } self->init_called = 1; self->flags = 0; self->unlock_gil = 1; self->lockmode = PYCBC_LOCKMODE_EXC; #define X(s, target, type) target, rv = PyArg_ParseTupleAndKeywords(args, kwargs, argspec, kwlist, XCTOR_ARGS(X) NULL); #undef X if (!rv) { PYCBC_EXCTHROW_ARGS(); return -1; } if (unlock_gil_O && PyObject_IsTrue(unlock_gil_O) == 0) { self->unlock_gil = 0; } create_opts.version = 3; create_opts.v.v3.type = conntype; if (iops_O && iops_O != Py_None) { self->iopswrap = pycbc_iowrap_new(self, iops_O); create_opts.v.v3.io = pycbc_iowrap_getiops(self->iopswrap); self->unlock_gil = 0; } if (dfl_fmt == Py_None || dfl_fmt == NULL) { /** Set to 0 if None or NULL */ dfl_fmt = pycbc_IntFromL(PYCBC_FMT_JSON); } else { Py_INCREF(dfl_fmt); /* later decref */ } rv = Bucket_set_format(self, dfl_fmt, NULL); Py_XDECREF(dfl_fmt); if (rv == -1) { return rv; } /** Set the transcoder */ if (tc && Bucket_set_transcoder(self, tc, NULL) == -1) { return -1; } #if defined(WITH_THREAD) if (!self->unlock_gil) { self->lockmode = PYCBC_LOCKMODE_NONE; } if (self->lockmode != PYCBC_LOCKMODE_NONE) { self->lock = PyThread_allocate_lock(); } #else self->unlock_gil = 0; self->lockmode = PYCBC_LOCKMODE_NONE; #endif err = lcb_create(&self->instance, &create_opts); if (err != LCB_SUCCESS) { self->instance = NULL; PYCBC_EXC_WRAP(PYCBC_EXC_LCBERR, err, "Couldn't create instance. Either bad " "credentials/hosts/bucket names were " "passed, or there was an internal error in creating the " "object"); return -1; } if (pycbc_log_handler) { err = lcb_cntl(self->instance, LCB_CNTL_SET, LCB_CNTL_LOGGER, &pycbc_lcb_logprocs); if (err != LCB_SUCCESS) { self->instance = NULL; PYCBC_EXC_WRAP(PYCBC_EXC_LCBERR, err, "Couldn't create log handler"); return -1; } } pycbc_callbacks_init(self->instance); lcb_set_cookie(self->instance, self); { const char *bucketstr; err = lcb_cntl(self->instance, LCB_CNTL_GET, LCB_CNTL_BUCKETNAME, &bucketstr); if (err == LCB_SUCCESS && bucketstr != NULL) { self->bucket = pycbc_SimpleStringZ(bucketstr); } } return 0; }
PyObject * pycbc_Connection__http_request(pycbc_Connection *self, PyObject *args, PyObject *kwargs) { int rv; int method; int reqtype; int quiet = 0; unsigned short value_format = 0; lcb_error_t err; const char *body = NULL; PyObject *ret = NULL; PyObject *quiet_O = NULL; PyObject *fetch_headers_O = Py_False; pycbc_strlen_t nbody = 0; const char *path = NULL; const char *content_type = NULL; pycbc_HttpResult *htres; lcb_http_request_t htreq = NULL; lcb_http_cmd_t htcmd = { 0 }; static char *kwlist[] = { "type", "method", "path", "content_type", "post_data", "response_format", "quiet", "fetch_headers", NULL }; rv = PyArg_ParseTupleAndKeywords(args, kwargs, "iis|zz#HOO", kwlist, &reqtype, &method, &path, &content_type, &body, &nbody, &value_format, &quiet_O, &fetch_headers_O); if (!rv) { PYCBC_EXCTHROW_ARGS(); return NULL; } if (quiet_O != NULL) { if (quiet_O == Py_None) { quiet = 0; } else { quiet = PyObject_IsTrue(quiet_O); } } htres = pycbc_httpresult_new(self); htres->key = pycbc_SimpleStringZ(path); htres->format = value_format; if (fetch_headers_O && PyObject_IsTrue(fetch_headers_O)) { htres->headers = PyDict_New(); } htcmd.v.v1.body = body; htcmd.v.v1.nbody = nbody; htcmd.v.v1.content_type = content_type; htcmd.v.v1.path = path; htcmd.v.v1.npath = strlen(path); htcmd.v.v1.method = method; err = lcb_make_http_request(self->instance, htres, reqtype, &htcmd, &htreq); if (err != LCB_SUCCESS) { PYCBC_EXCTHROW_SCHED(err); goto GT_DONE; } err = pycbc_oputil_wait_common(self); if (err != LCB_SUCCESS) { PYCBC_EXCTHROW_WAIT(err); goto GT_DONE; } if (quiet == 0 && pycbc_httpresult_ok(htres) == 0) { PYCBC_EXC_WRAP_EX(htres->rc ? PYCBC_EXC_LCBERR : PYCBC_EXC_HTTP, htres->rc, "HTTP Request failed. Examine 'objextra' for " "full result", htres->key, (PyObject*)htres); goto GT_DONE; } ret = (PyObject*)htres; htres = NULL; GT_DONE: Py_XDECREF(htres); return ret; }
PyObject * pycbc_Connection__http_request(pycbc_Connection *self, PyObject *args, PyObject *kwargs) { int rv; int method; int reqtype; unsigned short value_format = 0; lcb_error_t err; const char *body = NULL; PyObject *ret = NULL; PyObject *quiet_O = NULL; PyObject *chunked_O = NULL; PyObject *fetch_headers_O = Py_False; pycbc_strlen_t nbody = 0; const char *path = NULL; const char *content_type = NULL; pycbc_HttpResult *htres; lcb_http_request_t l_htreq; lcb_http_cmd_t htcmd = { 0 }; static char *kwlist[] = { "type", "method", "path", "content_type", "post_data", "response_format", "quiet", "fetch_headers", "chunked", NULL }; rv = PyArg_ParseTupleAndKeywords(args, kwargs, "iis|zz#HOOO", kwlist, &reqtype, &method, &path, &content_type, &body, &nbody, &value_format, &quiet_O, &fetch_headers_O, &chunked_O); if (!rv) { PYCBC_EXCTHROW_ARGS(); return NULL; } if (-1 == pycbc_oputil_conn_lock(self)) { return NULL; } htres = pycbc_httpresult_new(self); htres->key = pycbc_SimpleStringZ(path); htres->format = value_format; htres->htflags = 0; if (quiet_O != NULL && quiet_O != Py_None && PyObject_IsTrue(quiet_O)) { htres->htflags |= PYCBC_HTRES_F_QUIET; } if (fetch_headers_O && PyObject_IsTrue(fetch_headers_O)) { htres->headers = PyDict_New(); } if (chunked_O && PyObject_IsTrue(chunked_O)) { htcmd.v.v0.chunked = 1; htres->rctx = lcbex_vrow_create(); htres->rctx->callback = http_vrow_callback; htres->rctx->user_cookie = htres; htres->htflags |= PYCBC_HTRES_F_CHUNKED; } htcmd.v.v1.body = body; htcmd.v.v1.nbody = nbody; htcmd.v.v1.content_type = content_type; htcmd.v.v1.path = path; htcmd.v.v1.npath = strlen(path); htcmd.v.v1.method = method; err = lcb_make_http_request(self->instance, htres, reqtype, &htcmd, &l_htreq); if (err != LCB_SUCCESS) { PYCBC_EXCTHROW_SCHED(err); goto GT_DONE; } htres->htreq = l_htreq; if (htcmd.v.v0.chunked) { ret = (PyObject*)htres; htres = NULL; goto GT_DONE; } self->nremaining++; err = pycbc_oputil_wait_common(self); if (err != LCB_SUCCESS) { self->nremaining--; PYCBC_EXCTHROW_WAIT(err); goto GT_DONE; } if (maybe_raise(htres)) { goto GT_DONE; } ret = (PyObject*)htres; htres = NULL; GT_DONE: Py_XDECREF(htres); pycbc_oputil_conn_unlock(self); return ret; }