/** ******************************************************************************************************** * Get the current item count of the stack. * * @param self AerospikeLStack object * @param args The args is a tuple object containing an argument * list passed from Python to a C function * @param kwds Dictionary of keywords * * Returns the size of stack. * In case of error,appropriate exceptions will be raised. ******************************************************************************************************** */ PyObject * AerospikeLStack_Size(AerospikeLStack * self, PyObject * args, PyObject * kwds) { uint32_t size = 0; PyObject* py_policy = NULL; as_policy_apply apply_policy; as_policy_apply* apply_policy_p = NULL; as_error err; as_error_init(&err); static char * kwlist[] = {"policy", NULL}; // Python Function Argument Parsing if ( PyArg_ParseTupleAndKeywords(args, kwds, "|O:size", kwlist, &py_policy) == false ) { return NULL; } if (!self || !self->client || !self->client->as) { as_error_update(&err, AEROSPIKE_ERR_PARAM, "Invalid aerospike object"); goto CLEANUP; } if (!self->client->is_conn_16) { as_error_update(&err, AEROSPIKE_ERR_CLUSTER, "No connection to aerospike cluster"); goto CLEANUP; } // Convert python policy object to as_policy_apply pyobject_to_policy_apply(&err, py_policy, &apply_policy, &apply_policy_p, &self->client->as->config.policies.apply); if ( err.code != AEROSPIKE_OK ) { goto CLEANUP; } aerospike_lstack_size(self->client->as, &err, apply_policy_p, &self->key, &self->lstack, &size); CLEANUP: if ( err.code != AEROSPIKE_OK ) { PyObject * py_err = NULL; error_to_pyobject(&err, &py_err); PyErr_SetObject(PyExc_Exception, py_err); Py_DECREF(py_err); return NULL; } return PyLong_FromLong(size); }
/** ******************************************************************************************************* * This function will check whether operation can be performed * based on operation and value type. * * @param py_value The value to perform operations. * @param op The operation to perform. * * Returns 0 if operation can be performed. ******************************************************************************************************* */ int check_type(AerospikeClient * self, PyObject * py_value, int op, as_error *err) { if ((!PyInt_Check(py_value) && !PyLong_Check(py_value) && strcmp(py_value->ob_type->tp_name, "aerospike.null")) && (op == AS_OPERATOR_TOUCH)) { as_error_update(err, AEROSPIKE_ERR_PARAM, "Unsupported operand type(s) for touch : only int or long allowed"); return 1; } else if ( (!PyInt_Check(py_value) && !PyLong_Check(py_value) && (!PyFloat_Check(py_value) || !aerospike_has_double(self->as)) && strcmp(py_value->ob_type->tp_name, "aerospike.null")) && op == AS_OPERATOR_INCR){ as_error_update(err, AEROSPIKE_ERR_PARAM, "Unsupported operand type(s) for +: only 'int' allowed"); return 1; } else if ((!PyString_Check(py_value) && !PyUnicode_Check(py_value) && !PyByteArray_Check(py_value) && strcmp(py_value->ob_type->tp_name, "aerospike.null")) && (op == AS_OPERATOR_APPEND || op == AS_OPERATOR_PREPEND)) { as_error_update(err, AEROSPIKE_ERR_PARAM, "Cannot concatenate 'str' and 'non-str' objects"); return 1; } return 0; }
static void as_uv_connect(as_event_command* cmd) { int fd = as_event_create_socket(cmd); if (fd < 0) { return; } as_event_connection* conn = cmd->conn; uv_tcp_t* socket = &conn->socket; int status = uv_tcp_init(cmd->event_loop->loop, socket); if (status) { as_error err; as_error_update(&err, AEROSPIKE_ERR_ASYNC_CONNECTION, "uv_tcp_init failed: %s", uv_strerror(status)); // Call standard event connection error handler because as_uv_connect_error() requires that // uv_tcp_init() has already succeeded. as_event_connect_error(cmd, &err, fd); return; } // Define externally created fd to uv_tcp_t. status = uv_tcp_open(socket, fd); if (status) { as_error err; as_error_update(&err, AEROSPIKE_ERR_ASYNC_CONNECTION, "uv_tcp_open failed: %s", uv_strerror(status)); // Close fd directly because we created it outside of libuv and uv_tcp_t does not know about it here. close(fd); as_uv_connect_error(cmd, &err); return; } socket->data = conn; conn->req.connect.data = cmd; as_node* node = cmd->node; as_address* primary = as_vector_get(&node->addresses, node->address_index); status = uv_tcp_connect(&conn->req.connect, socket, (struct sockaddr*)&primary->addr, as_uv_connected); if (status) { as_error err; as_error_update(&err, AEROSPIKE_ERR_ASYNC_CONNECTION, "uv_tcp_connect failed: %s", uv_strerror(status)); as_uv_connect_error(cmd, &err); } }
PyObject * AerospikeGeospatial_Unwrap(AerospikeGeospatial * self, PyObject * args, PyObject * kwds) { // Python function arguments // Python function keyword arguments static char * kwlist[] = {NULL}; if ( PyArg_ParseTupleAndKeywords(args, kwds, ":unwrap", kwlist) == false ){ return NULL; } // Aerospike error object as_error err; // Initialize error object as_error_init(&err); if ( !self ){ as_error_update(&err, AEROSPIKE_ERR_PARAM, "Invalid geospatial object"); goto CLEANUP; } CLEANUP: // If an error occurred, tell Python. if ( err.code != AEROSPIKE_OK ) { PyObject * py_err = NULL; error_to_pyobject(&err, &py_err); PyObject *exception_type = raise_exception(&err); PyErr_SetObject(exception_type, py_err); Py_DECREF(py_err); return NULL; } Py_INCREF(self->geo_data); return self->geo_data; }
static void as_uv_connected(uv_connect_t* req, int status) { if (uv_is_closing((uv_handle_t*)req->handle)) { return; } as_event_command* cmd = req->data; if (status == 0) { if (cmd->cluster->user) { as_uv_auth_write_start(cmd, req->handle); } else { as_uv_command_write_start(cmd, req->handle); } } else if (status != UV_ECANCELED) { as_node* node = cmd->node; as_address* primary = as_vector_get(&node->addresses, node->address_index); as_error err; as_error_update(&err, AEROSPIKE_ERR_ASYNC_CONNECTION, "Failed to connect: %s %s:%d", node->name, primary->name, (int)cf_swap_from_be16(primary->addr.sin_port)); as_uv_connect_error(cmd, &err); } }
bool user_callback_wrapper(const as_val *val, void *udata) { zval retval; ZVAL_NULL(&retval); if (!val) { return false; } as_record* record = as_record_fromval(val); user_callback_function* callback_info = (user_callback_function*)udata; pthread_mutex_lock(callback_info->cb_mutex); callback_info->callback.retval = &retval; if (execute_user_callback(record, callback_info) != AEROSPIKE_OK) { as_error_update(callback_info->err, AEROSPIKE_ERR_PARAM, "Callback raised an error"); pthread_mutex_unlock(callback_info->cb_mutex); return false; } if (callback_info->callback.retval && Z_TYPE_P(callback_info->callback.retval) == IS_FALSE) { pthread_mutex_unlock(callback_info->cb_mutex); return false; } zval_dtor(&retval); pthread_mutex_unlock(callback_info->cb_mutex); return true; }
static bool each_result(const as_val * val, void * udata) { bool rval = true; if ( !val ) { return false; } // Extract callback user-data LocalData * data = (LocalData *) udata; as_error * err = &data->error; PyObject * py_callback = data->callback; // Python Function Arguments and Result Value PyObject * py_arglist = NULL; PyObject * py_result = NULL; PyObject * py_return = NULL; // Lock Python State PyGILState_STATE gstate; gstate = PyGILState_Ensure(); // Convert as_val to a Python Object val_to_pyobject(err, val, &py_result); // Build Python Function Arguments py_arglist = PyTuple_New(1); PyTuple_SetItem(py_arglist, 0, py_result); // Invoke Python Callback py_return = PyEval_CallObject(py_callback, py_arglist); // Release Python Function Arguments Py_DECREF(py_arglist); // handle return value if ( py_return == NULL ) { // an exception was raised, handle it (someday) // for now, we bail from the loop as_error_update(err, AEROSPIKE_ERR_PARAM, "Callback function contains an error"); rval = true; } else if ( PyBool_Check(py_return) ) { if ( Py_False == py_return ) { rval = false; } else { rval = true; } Py_DECREF(py_return); } else { rval = true; Py_DECREF(py_return); } // Release Python State PyGILState_Release(gstate); return rval; }
PyObject * AerospikeGeospatial_DoDumps(PyObject *geo_data, as_error *err) { PyObject *initresult = NULL; PyObject* sysmodules = PyImport_GetModuleDict(); PyObject* json_module = NULL; if (PyMapping_HasKeyString(sysmodules, "json")) { json_module = PyMapping_GetItemString(sysmodules, "json"); } else { json_module = PyImport_ImportModule("json"); } if (!json_module) { /* insert error handling here! and exit this function */ as_error_update(err, AEROSPIKE_ERR_CLIENT, "Unable to load json module"); } else { PyObject *py_funcname = PyString_FromString("dumps"); Py_INCREF(json_module); initresult = PyObject_CallMethodObjArgs(json_module, py_funcname, geo_data, NULL); Py_DECREF(json_module); Py_DECREF(py_funcname); } return initresult; }
as_status as_key_set_digest(as_error* err, as_key* key) { if (key->digest.init) { return AEROSPIKE_OK; } size_t set_len = strlen(key->set); size_t size; as_val* val = (as_val*)key->valuep; uint8_t* buf; switch (val->type) { case AS_INTEGER: { as_integer* v = as_integer_fromval(val); size = 9; buf = alloca(size); buf[0] = AS_BYTES_INTEGER; *(uint64_t*)&buf[1] = cf_swap_to_be64(v->value); break; } case AS_DOUBLE: { as_double* v = as_double_fromval(val); size = 9; buf = alloca(size); buf[0] = AS_BYTES_DOUBLE; *(double*)&buf[1] = cf_swap_to_big_float64(v->value); break; } case AS_STRING: { as_string* v = as_string_fromval(val); size_t len = as_string_len(v); size = len + 1; buf = alloca(size); buf[0] = AS_BYTES_STRING; memcpy(&buf[1], v->value, len); break; } case AS_BYTES: { as_bytes* v = as_bytes_fromval(val); size = v->size + 1; buf = alloca(size); // Note: v->type must be a blob type (AS_BYTES_BLOB, AS_BYTES_JAVA, AS_BYTES_PYTHON ...). // Otherwise, the particle type will be reassigned to a non-blob which causes a // mismatch between type and value. buf[0] = v->type; memcpy(&buf[1], v->value, v->size); break; } default: { return as_error_update(err, AEROSPIKE_ERR_PARAM, "Invalid key type: %d", val->type); } } cf_digest_compute2(key->set, set_len, buf, size, (cf_digest*)key->digest.value); key->digest.init = true; return AEROSPIKE_OK; }
static bool AerospikeClient_InfoAll_each(as_error * err, const as_node * node, const char * req, char * res, void * udata) { PyObject * py_err = NULL; PyObject * py_ustr = NULL; PyObject * py_out = NULL; foreach_callback_info_udata* udata_ptr = (foreach_callback_info_udata *) udata; // Need to make sure we have the GIL since we're back in python land now PyGILState_STATE gil_state = PyGILState_Ensure(); if (err && err->code != AEROSPIKE_OK) { as_error_update(err, err->code, NULL); goto CLEANUP; } py_out = get_formatted_info_response(res); /* Since this is called from aerospike_info_foreach, we do not own res, so there is no need to free it */ if (!py_err) { Py_INCREF(Py_None); py_err = Py_None; } PyObject * py_res = PyTuple_New(2); PyTuple_SetItem(py_res, 0, py_err); PyTuple_SetItem(py_res, 1, py_out); PyObject * py_nodes = (PyObject *) udata_ptr->udata_p; PyDict_SetItemString(py_nodes, node->name, py_res); Py_DECREF(py_res); CLEANUP: if (py_ustr) { Py_DECREF(py_ustr); } if (udata_ptr->error.code != AEROSPIKE_OK) { PyObject * py_err = NULL; error_to_pyobject( &udata_ptr->error, &py_err); PyObject *exception_type = raise_exception(&udata_ptr->error); PyErr_SetObject(exception_type, py_err); Py_DECREF(py_err); PyGILState_Release(gil_state); return false; } if (err->code != AEROSPIKE_OK) { PyObject * py_err = NULL; error_to_pyobject(err, &py_err); PyObject *exception_type = raise_exception(err); PyErr_SetObject(exception_type, py_err); Py_DECREF(py_err); PyGILState_Release(gil_state); return false; } PyGILState_Release(gil_state); return true; }
/** * Scan the records in the specified namespace and set for a single node. * * The callback function will be called for each record scanned. When all records have * been scanned, then callback will be called with a NULL value for the record. * * ~~~~~~~~~~{.c} * char* node_names = NULL; * int n_nodes = 0; * as_cluster_get_node_names(as->cluster, &n_nodes, &node_names); * * if (n_nodes <= 0) * return <error>; * * as_scan scan; * as_scan_init(&scan, "test", "demo"); * * if (aerospike_scan_node(&as, &err, NULL, &scan, node_names[0], callback, NULL) != AEROSPIKE_OK ) { * fprintf(stderr, "error(%d) %s at [%s:%d]", err.code, err.message, err.file, err.line); * } * * free(node_names); * as_scan_destroy(&scan); * ~~~~~~~~~~ * * @param as The aerospike instance to use for this operation. * @param err The as_error to be populated if an error occurs. * @param policy The policy to use for this operation. If NULL, then the default policy will be used. * @param scan The scan to execute against the cluster. * @param node_name The node name to scan. * @param callback The function to be called for each record scanned. * @param udata User-data to be passed to the callback. * * @return AEROSPIKE_OK on success. Otherwise an error occurred. */ as_status aerospike_scan_node( aerospike * as, as_error * err, const as_policy_scan * policy, const as_scan * scan, const char* node_name, aerospike_scan_foreach_callback callback, void * udata) { as_error_reset(err); if (! policy) { policy = &as->config.policies.scan; } // Retrieve node. as_node* node = as_node_get_by_name(as->cluster, node_name); if (! node) { return as_error_update(err, AEROSPIKE_ERR_PARAM, "Invalid node name: %s", node_name); } // Create scan command uint64_t task_id = cf_get_rand64() / 2; as_buffer argbuffer; uint16_t n_fields = 0; size_t size = as_scan_command_size(scan, &n_fields, &argbuffer); uint8_t* cmd = as_command_init(size); size = as_scan_command_init(cmd, policy, scan, task_id, n_fields, &argbuffer); // Initialize task. uint32_t error_mutex = 0; as_scan_task task; task.node = node; task.cluster = as->cluster; task.policy = policy; task.scan = scan; task.callback = callback; task.udata = udata; task.err = err; task.complete_q = 0; task.error_mutex = &error_mutex; task.task_id = task_id; task.cmd = cmd; task.cmd_size = size; // Run scan. as_status status = as_scan_command_execute(&task); // Free command memory. as_command_free(cmd, size); // Release node. as_node_release(node); // If completely successful, make the callback that signals completion. if (callback && status == AEROSPIKE_OK) { callback(NULL, udata); } return status; }
static int AerospikeGeospatial_Type_Init(AerospikeGeospatial * self, PyObject * args, PyObject * kwds) { PyObject *py_geodata = NULL; PyObject* initresult = NULL; as_error err; as_error_init(&err); static char * kwlist[] = {"geo_data", NULL}; if (PyArg_ParseTupleAndKeywords(args, kwds, "O:GeoJSON", kwlist, &py_geodata) == false) { as_error_update(&err, AEROSPIKE_ERR_PARAM, "GeoJSON() expects exactly 1 parameter"); goto CLEANUP; } if (PyString_Check(py_geodata)) { initresult = AerospikeGeospatial_DoLoads(py_geodata, &err); if (!initresult) { as_error_update(&err, AEROSPIKE_ERR_CLIENT, "String is not GeoJSON serializable"); goto CLEANUP; } store_geodata(self, &err, initresult); } else { store_geodata(self, &err, py_geodata); } CLEANUP: if (err.code != AEROSPIKE_OK) { PyObject * py_err = NULL; error_to_pyobject(&err, &py_err); PyObject *exception_type = raise_exception(&err); PyErr_SetObject(exception_type, py_err); Py_DECREF(py_err); return -1; } Py_INCREF(self->geo_data); if (initresult) { Py_DECREF(initresult); } return 0; }
/** ******************************************************************************************************* * This function checks for metadata and if present set it into the * as_operations. * * @param py_meta The dictionary of metadata. * @param ops The as_operations object. * @param err The as_error to be populated by the function * with the encountered error if any. * * Returns nothing. ******************************************************************************************************* */ static void AerospikeClient_CheckForMeta(PyObject * py_meta, as_operations * ops, as_error *err) { if ( py_meta && PyDict_Check(py_meta) ) { PyObject * py_gen = PyDict_GetItemString(py_meta, "gen"); PyObject * py_ttl = PyDict_GetItemString(py_meta, "ttl"); uint32_t ttl = 0; uint16_t gen = 0; if ( py_ttl != NULL ){ if ( PyInt_Check(py_ttl) ) { ttl = (uint32_t) PyInt_AsLong(py_ttl); } else if ( PyLong_Check(py_ttl) ) { ttl = (uint32_t) PyLong_AsLongLong(py_ttl); } else { as_error_update(err, AEROSPIKE_ERR_PARAM, "Ttl should be an int or long"); } if((uint32_t)-1 == ttl) { as_error_update(err, AEROSPIKE_ERR_PARAM, "integer value for ttl exceeds sys.maxsize"); return; } ops->ttl = ttl; } if( py_gen != NULL ){ if ( PyInt_Check(py_gen) ) { gen = (uint16_t) PyInt_AsLong(py_gen); } else if ( PyLong_Check(py_gen) ) { gen = (uint16_t) PyLong_AsLongLong(py_gen); } else { as_error_update(err, AEROSPIKE_ERR_PARAM, "Generation should be an int or long"); } if((uint16_t)-1 == gen) { as_error_update(err, AEROSPIKE_ERR_PARAM, "integer value for gen exceeds sys.maxsize"); return; } ops->gen = gen; } } else { as_error_update(err, AEROSPIKE_ERR_PARAM, "Metadata should be of type dictionary"); } }
/******************************************************************************* * PYTHON TYPE HOOKS ******************************************************************************/ void store_geodata(AerospikeGeospatial *self, as_error *err, PyObject *py_geodata) { if (PyDict_Check(py_geodata)) { if (self->geo_data) { Py_DECREF(self->geo_data); } self->geo_data = py_geodata; } else { as_error_update(err, AEROSPIKE_ERR_PARAM, "Geospatial data should be a dictionary or raw GeoJSON string"); } }
static int as_ev_write(as_event_command* cmd) { int fd = cmd->conn->fd; ssize_t bytes; do { #if defined(__linux__) bytes = send(fd, cmd->buf + cmd->pos, cmd->len - cmd->pos, MSG_NOSIGNAL); #else bytes = write(fd, cmd->buf + cmd->pos, cmd->len - cmd->pos); #endif if (bytes > 0) { cmd->pos += bytes; continue; } if (bytes < 0) { if (errno == EWOULDBLOCK) { return AS_EVENT_WRITE_INCOMPLETE; } as_error err; as_error_update(&err, AEROSPIKE_ERR_ASYNC_CONNECTION, "Socket %d write failed: %d", fd, errno); as_event_socket_error(cmd, &err); return AS_EVENT_WRITE_ERROR; } else { as_error err; as_error_update(&err, AEROSPIKE_ERR_ASYNC_CONNECTION, "Socket %d write closed by peer", fd); as_event_socket_error(cmd, &err); return AS_EVENT_WRITE_ERROR; } } while (cmd->pos < cmd->len); return AS_EVENT_WRITE_COMPLETE; }
static void as_uv_command_write_complete(uv_write_t* req, int status) { if (!as_uv_connection_alive(req->handle)) { return; } as_event_command* cmd = req->data; if (status == 0) { cmd->len = sizeof(as_proto); cmd->pos = 0; cmd->state = AS_ASYNC_STATE_READ_HEADER; if (cmd->pipe_listener != NULL) { as_pipe_read_start(cmd); as_pipe_connection* conn = (as_pipe_connection*)cmd->conn; // There already was an active reader for a previous command. if (cf_ll_size(&conn->readers) > 1) { return; } } status = uv_read_start(req->handle, as_uv_command_buffer, as_uv_command_read); if (status) { as_error err; as_error_update(&err, AEROSPIKE_ERR_ASYNC_CONNECTION, "uv_read_start failed: %s", uv_strerror(status)); as_event_socket_error(cmd, &err); } } else if (status != UV_ECANCELED) { as_error err; as_error_update(&err, AEROSPIKE_ERR_ASYNC_CONNECTION, "Socket write failed: %s", uv_strerror(status)); as_event_socket_error(cmd, &err); } }
as_status as_command_parse_success_failure_bins(uint8_t** pp, as_error* err, as_msg* msg, as_val** value) { uint8_t* p = *pp; p = as_command_ignore_fields(p, msg->n_fields); as_bin_name name; for (uint32_t i = 0; i < msg->n_ops; i++) { uint32_t op_size = cf_swap_from_be32(*(uint32_t*)p); p += 5; uint8_t type = *p; p += 2; uint8_t name_size = *p++; uint8_t name_len = (name_size <= AS_BIN_NAME_MAX_LEN)? name_size : AS_BIN_NAME_MAX_LEN; memcpy(name, p, name_len); name[name_len] = 0; p += name_size; uint32_t value_size = (op_size - (name_size + 4)); if (strcmp(name, "SUCCESS") == 0) { if (value) { as_command_parse_value(p, type, value_size, value); } *pp = p + value_size; return AEROSPIKE_OK; } if (strcmp(name, "FAILURE") == 0) { as_val* val = 0; as_command_parse_value(p, type, value_size, &val); if (val == 0) { as_error_set_message(err, AEROSPIKE_ERR_CLIENT, "Received null FAILURE bin."); } else if (val->type == AS_STRING) { as_error_set_message(err, AEROSPIKE_ERR_CLIENT, ((as_string*)val)->value); } else { as_error_update(err, AEROSPIKE_ERR_CLIENT, "Expected string for FAILURE bin. Received %d", val->type); } as_val_destroy(val); return err->code; } p += value_size; } return as_error_set_message(err, AEROSPIKE_ERR_CLIENT, "Failed to find SUCCESS or FAILURE bin."); }
static void as_ev_parse_authentication(as_event_command* cmd) { if (cmd->state == AS_ASYNC_STATE_AUTH_READ_HEADER) { // Read response length if (! as_ev_read(cmd)) { return; } as_event_set_auth_parse_header(cmd); if (cmd->len > cmd->capacity) { as_error err; as_error_update(&err, AEROSPIKE_ERR_CLIENT, "Authenticate response size is corrupt: %u", cmd->auth_len); as_event_socket_error(cmd, &err); return; } } if (! as_ev_read(cmd)) { return; } // Parse authentication response. cmd->len -= cmd->auth_len; uint8_t code = cmd->buf[cmd->len + AS_ASYNC_AUTH_RETURN_CODE]; if (code) { // Can't authenticate socket, so must close it. as_error err; as_error_update(&err, code, "Authentication failed: %s", as_error_string(code)); as_event_socket_error(cmd, &err); return; } cmd->pos = 0; as_ev_command_write_start(cmd); }
PyObject * AerospikeClient_HasGeo(AerospikeClient * self, PyObject * args, PyObject * kwds) { // Initialize error as_error err; as_error_init(&err); if (!self || !self->as) { as_error_update(&err, AEROSPIKE_ERR_PARAM, "Invalid aerospike object"); goto CLEANUP; } if (!self->is_conn_16) { as_error_update(&err, AEROSPIKE_ERR_CLUSTER, "No connection to aerospike cluster"); goto CLEANUP; } if (aerospike_has_geo(self->as)) { Py_INCREF(Py_True); return Py_True; } Py_INCREF(Py_False); return Py_False; CLEANUP: if (err.code != AEROSPIKE_OK) { PyObject * py_err = NULL; error_to_pyobject(&err, &py_err); PyObject *exception_type = raise_exception(&err); PyErr_SetObject(exception_type, py_err); Py_DECREF(py_err); return NULL; } return NULL; }
/** ******************************************************************************************************* * Closes already opened connection to the database. * * @param self AerospikeClient object * @param args The args is a tuple object containing an argument * list passed from Python to a C function * @param kwds Dictionary of keywords * * Returns None. * In case of error,appropriate exceptions will be raised. ******************************************************************************************************* */ PyObject * AerospikeClient_Close(AerospikeClient * self, PyObject * args, PyObject * kwds) { as_error err; char *alias_to_search = NULL; // Initialize error as_error_init(&err); if (!self || !self->as) { as_error_update(&err, AEROSPIKE_ERR_PARAM, "Invalid aerospike object"); goto CLEANUP; } alias_to_search = return_search_string(self->as); PyObject *py_persistent_item = NULL; py_persistent_item = PyDict_GetItemString(py_global_hosts, alias_to_search); if (py_persistent_item) { close_aerospike_object(self->as, &err, alias_to_search, py_persistent_item); } else { aerospike_close(self->as, &err); for (unsigned int i = 0; i < self->as->config.hosts_size; i++) { free((void *) self->as->config.hosts[i].addr); } Py_BEGIN_ALLOW_THREADS aerospike_destroy(self->as); Py_END_ALLOW_THREADS } self->is_conn_16 = false; self->as = NULL; PyMem_Free(alias_to_search); alias_to_search = NULL; Py_INCREF(Py_None); CLEANUP: if ( err.code != AEROSPIKE_OK ) { PyObject * py_err = NULL; error_to_pyobject(&err, &py_err); PyObject *exception_type = raise_exception(&err); PyErr_SetObject(exception_type, py_err); Py_DECREF(py_err); return NULL; } return Py_None; }
/** ****************************************************************************************************** * Set a serializer in the aerospike database * * @param self Aerospike object * @param args The args is a tuple object containing an argument * list passed from Python to a C function * @param kwds Dictionary of keywords * * Returns integer handle for the serializer being set. ******************************************************************************************************* */ PyObject * AerospikeClient_Set_Serializer(AerospikeClient * self, PyObject * args, PyObject * kwds) { // Python Function Arguments PyObject * py_func = NULL; // Python Function Keyword Arguments static char * kwlist[] = {"function", NULL}; as_error err; // Initialize error as_error_init(&err); // Python Function Argument Parsing if ( PyArg_ParseTupleAndKeywords(args, kwds, "O:set_serializer", kwlist, &py_func) == false ) { return NULL; } if (!is_user_serializer_registered) { memset(&user_serializer_call_info, 0, sizeof(user_serializer_call_info)); } if (user_serializer_call_info.callback == py_func) { return PyLong_FromLong(0); } if (!PyCallable_Check(py_func)) { as_error_update(&err, AEROSPIKE_ERR_PARAM, "Parameter must be a callable"); goto CLEANUP; } if (user_serializer_call_info.callback != NULL) { Py_DECREF(user_serializer_call_info.callback); } is_user_serializer_registered = 1; user_serializer_call_info.callback = py_func; Py_INCREF(py_func); CLEANUP: if ( err.code != AEROSPIKE_OK ) { PyObject * py_err = NULL; error_to_pyobject(&err, &py_err); PyObject *exception_type = raise_exception(&err); PyErr_SetObject(exception_type, py_err); Py_DECREF(py_err); return NULL; } return PyLong_FromLong(0); }
as_status aerospike_scan_node_async( aerospike* as, as_error* err, const as_policy_scan* policy, const as_scan* scan, uint64_t* scan_id, const char* node_name, as_async_scan_listener listener, void* udata, as_event_loop* event_loop ) { as_error_reset(err); // Retrieve and reserve node. as_node* node = as_node_get_by_name(as->cluster, node_name); if (! node) { return as_error_update(err, AEROSPIKE_ERR_PARAM, "Invalid node name: %s", node_name); } return as_scan_async(as, err, policy, scan, scan_id, listener, udata, event_loop, &node, 1); }
static inline void as_uv_command_write_start(as_event_command* cmd, uv_stream_t* stream) { cmd->state = AS_ASYNC_STATE_WRITE; uv_write_t* write_req = &cmd->conn->req.write; write_req->data = cmd; uv_buf_t buf = uv_buf_init((char*)cmd->buf, cmd->len); int status = uv_write(write_req, stream, &buf, 1, as_uv_command_write_complete); if (status) { as_error err; as_error_update(&err, AEROSPIKE_ERR_ASYNC_CONNECTION, "uv_write failed: %s", uv_strerror(status)); as_event_socket_error(cmd, &err); } }
/** * @return AEROSPIKE_OK if successful. Otherwise an error occurred. */ as_status aerospike_udf_put( aerospike * as, as_error * err, const as_policy_info * policy, const char * filename, as_udf_type type, as_bytes * content) { if (type != AS_UDF_TYPE_LUA) { return as_error_update(err, AEROSPIKE_ERR_PARAM, "Invalid udf type: %d", type); } as_error_reset(err); if (! policy) { policy = &as->config.policies.info; } char* command = NULL; as_string filename_string; const char* filebase = as_basename(&filename_string, filename); uint32_t encoded_len = cf_b64_encoded_len(content->size); char* content_base64 = malloc(encoded_len + 1); cf_b64_encode(content->value, content->size, content_base64); content_base64[encoded_len] = 0; if (! asprintf(&command, "udf-put:filename=%s;content=%s;content-len=%d;udf-type=%s;", filebase, content_base64, encoded_len, as_udf_type_str[type])) { as_string_destroy(&filename_string); free(content_base64); return as_error_set_message(err, AEROSPIKE_ERR_CLIENT, "Udf put asprintf failed"); } as_string_destroy(&filename_string); char* response = 0; as_status status = aerospike_info_any(as, err, policy, command, &response); free(command); free(content_base64); if (status) { return status; } free(response); return AEROSPIKE_OK; }
as_status as_lookup(as_cluster* cluster, as_error* err, char* hostname, uint16_t port, as_vector* /*<struct sockaddr_in>*/ addresses) { // Check if there is an alternate address that should be used for this hostname. if (cluster && cluster->ip_map) { as_addr_map* entry = cluster->ip_map; for (uint32_t i = 0; i < cluster->ip_map_size; i++) { if (strcmp(entry->orig, hostname) == 0) { // Found mapping for this address. Use alternate. as_log_debug("Using %s instead of %s", entry->alt, hostname); hostname = entry->alt; break; } entry++; } } // Lookup TCP addresses. struct addrinfo hints; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET; struct addrinfo* results = 0; int ret = getaddrinfo(hostname, 0, &hints, &results); if (ret) { return as_error_update(err, AEROSPIKE_ERR_INVALID_HOST, "Invalid hostname %s: %s", hostname, gai_strerror(ret)); } // Add addresses to vector if it exists. if (addresses) { uint16_t port_be = cf_swap_to_be16(port); for (struct addrinfo* r = results; r; r = r->ai_next) { struct sockaddr_in* addr = (struct sockaddr_in*)r->ai_addr; addr->sin_port = port_be; as_vector_append_unique(addresses, addr); } } freeaddrinfo(results); return AEROSPIKE_OK; }
as_status as_command_compress(as_error* err, uint8_t* cmd, size_t cmd_sz, uint8_t* compressed_cmd, size_t* compressed_size) { *compressed_size -= sizeof(as_compressed_proto); int ret_val = compress2(compressed_cmd + sizeof(as_compressed_proto), compressed_size, cmd, cmd_sz, Z_DEFAULT_COMPRESSION); if (ret_val) { return as_error_update(err, AEROSPIKE_ERR_CLIENT, "Compress failed: %d", ret_val); } // compressed_size will now have to actual compressed size from compress2() as_command_compress_write_end(compressed_cmd, compressed_cmd + sizeof(as_compressed_proto) + *compressed_size, cmd_sz); // Adjust the compressed size to include the header size *compressed_size += sizeof(as_compressed_proto); return AEROSPIKE_OK; }
as_connection_status as_event_get_connection(as_event_command* cmd) { as_queue* queue = &cmd->node->async_conn_qs[cmd->event_loop->index]; as_async_connection* conn; // Find connection. while (as_queue_pop(queue, &conn)) { ck_pr_dec_32(&cmd->cluster->async_conn_pool); // Verify that socket is active and receive buffer is empty. int len = as_event_validate_connection(&conn->base); if (len == 0) { conn->cmd = cmd; cmd->conn = (as_event_connection*)conn; return AS_CONNECTION_FROM_POOL; } as_log_debug("Invalid async socket from pool: %d", len); as_event_release_connection(cmd->cluster, &conn->base, queue); } // Create connection structure only when node connection count within queue limit. if (as_queue_incr_total(queue)) { ck_pr_inc_32(&cmd->cluster->async_conn_count); conn = cf_malloc(sizeof(as_async_connection)); conn->base.pipeline = false; conn->cmd = cmd; cmd->conn = &conn->base; return AS_CONNECTION_NEW; } else { as_error err; as_error_update(&err, AEROSPIKE_ERR_NO_MORE_CONNECTIONS, "Max node/event loop %s async connections would be exceeded: %u", cmd->node->name, queue->capacity); as_event_stop_timer(cmd); as_event_error_callback(cmd, &err); return AS_CONNECTION_TOO_MANY; } }
AerospikeClient * AerospikeClient_New(PyObject * parent, PyObject * args, PyObject * kwds) { AerospikeClient * self = (AerospikeClient *) AerospikeClient_Type.tp_new(&AerospikeClient_Type, args, kwds); if ( AerospikeClient_Type.tp_init((PyObject *) self, args, kwds) == 0 ){ // Initialize connection flag self->is_conn_16 = false; return self; } else { as_error err; as_error_init(&err); as_error_update(&err, AEROSPIKE_ERR_PARAM, "Parameters are incorrect"); PyObject * py_err = NULL; error_to_pyobject(&err, &py_err); PyObject *exception_type = raise_exception(&err); PyErr_SetObject(exception_type, py_err); Py_DECREF(py_err); return NULL; } }
as_status as_command_parse_header(as_error* err, int fd, uint64_t deadline_ms, void* user_data) { // Read header as_proto_msg* msg = user_data; as_status status = as_socket_read_deadline(err, fd, (uint8_t*)msg, sizeof(as_proto_msg), deadline_ms); if (status) { return status; } // Ensure that there is no data left to read. as_proto_swap_from_be(&msg->proto); as_msg_swap_header_from_be(&msg->m); size_t size = msg->proto.sz - msg->m.header_sz; if (size > 0) { as_log_warn("Unexpected data received from socket after a write: fd=%d size=%zu", fd, size); // Verify size is not corrupted. if (size > 100000) { // The socket will be closed on this error, so we don't have to worry about emptying it. return as_error_update(err, AEROSPIKE_ERR_CLIENT, "Unexpected data received from socket after a write: fd=%d size=%zu", fd, size); } // Empty socket. uint8_t* buf = cf_malloc(size); status = as_socket_read_deadline(err, fd, buf, size, deadline_ms); cf_free(buf); if (status) { return status; } } if (msg->m.result_code) { return as_error_set_message(err, msg->m.result_code, as_error_string(msg->m.result_code)); } return msg->m.result_code; }
AerospikeLList * AerospikeLList_New(AerospikeClient * client, PyObject * args, PyObject * kwds) { AerospikeLList * self = (AerospikeLList *) AerospikeLList_Type.tp_new(&AerospikeLList_Type, args, kwds); self->client = client; Py_INCREF(client); if (AerospikeLList_Type.tp_init((PyObject *)self, args, kwds) == 0) { return self; } else { as_error err; as_error_init(&err); as_error_update(&err, AEROSPIKE_ERR_PARAM, "Parameters are incorrect"); PyObject * py_err = NULL; PyObject * py_key = NULL; PyObject *exception_type = raise_exception(&err); error_to_pyobject(&err, &py_err); if(PyObject_HasAttrString(exception_type, "key")) { if(&self->key) { key_to_pyobject(&err, &self->key, &py_key); PyObject_SetAttrString(exception_type, "key", py_key); Py_DECREF(py_key); } else { PyObject_SetAttrString(exception_type, "key", Py_None); } } if(PyObject_HasAttrString(exception_type, "bin")) { if(&self->bin_name) { PyObject *py_bins = PyStr_FromString((char *)&self->bin_name); PyObject_SetAttrString(exception_type, "bin", py_bins); Py_DECREF(py_bins); } else { PyObject_SetAttrString(exception_type, "bin", Py_None); } } PyErr_SetObject(exception_type, py_err); Py_DECREF(py_err); return NULL; } }