/**
 ********************************************************************************************************
 * 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);
}
Exemplo n.º 2
0
/**
 *******************************************************************************************************
 * 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;
}
Exemplo n.º 3
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);
	}
}
Exemplo n.º 4
0
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;
}
Exemplo n.º 5
0
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;
}
Exemplo n.º 8
0
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;
}
Exemplo n.º 9
0
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;
}
Exemplo n.º 10
0
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;
}
Exemplo n.º 12
0
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;
}
Exemplo n.º 13
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");
	}
}
Exemplo n.º 14
0
/*******************************************************************************
 * 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");
	}
}
Exemplo n.º 15
0
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;
}
Exemplo n.º 16
0
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);
	}
}
Exemplo n.º 17
0
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.");
}
Exemplo n.º 18
0
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);
}
Exemplo n.º 19
0
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;
}
Exemplo n.º 20
0
/**
 *******************************************************************************************************
 * 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;
}
Exemplo n.º 21
0
/**
 ******************************************************************************************************
 * 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);
}
Exemplo n.º 22
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);
}
Exemplo n.º 23
0
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);
	}
}
Exemplo n.º 24
0
/**
 * @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;
}
Exemplo n.º 25
0
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;
}
Exemplo n.º 26
0
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;
}
Exemplo n.º 27
0
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;
    }
}
Exemplo n.º 28
0
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;
	}
}
Exemplo n.º 29
0
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;
}
Exemplo n.º 30
0
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;
	}
}