PyObject * AerospikeQuery_Foreach(AerospikeQuery * self, PyObject * args, PyObject * kwds)
{
	// Python Function Arguments
	PyObject * py_callback = NULL;
	PyObject * py_policy = NULL;

	// Python Function Keyword Arguments
	static char * kwlist[] = {"callback", "policy", NULL};

	// Python Function Argument Parsing
	if ( PyArg_ParseTupleAndKeywords(args, kwds, "O|O:foreach", kwlist, &py_callback, &py_policy) == false ) {
		return NULL;
	}

	// Aerospike Client Arguments
	as_error err;
	as_policy_query policy;
	as_policy_query * policy_p = NULL;

	// Initialize error
	as_error_init(&err);

	// Convert python policy object to as_policy_exists
	pyobject_to_policy_query(&err, py_policy, &policy, &policy_p);
	if ( err.code != AEROSPIKE_OK ) {
		goto CLEANUP;
	}

	// Create and initialize callback user-data
	LocalData data;
	data.callback = py_callback;
	as_error_init(&data.error);

	// We are spawning multiple threads
	PyThreadState * _save = PyEval_SaveThread();
	
	// Invoke operation
	aerospike_query_foreach(self->client->as, &err, policy_p, &self->query, each_result, &data);

	// We are done using multiple threads
	PyEval_RestoreThread(_save);
	
CLEANUP:

	if ( err.code != AEROSPIKE_OK ) {
		PyObject * py_err = NULL;
		error_to_pyobject(&err, &py_err);
		PyErr_SetObject(PyExc_Exception, py_err);
		return NULL;
	}

	Py_INCREF(Py_None);
	return Py_None;
}
PyObject * AerospikeQuery_Results(AerospikeQuery * self, PyObject * args, PyObject * kwds)
{
	PyObject * py_policy = NULL;
	
	static char * kwlist[] = {"policy", NULL};

	if ( PyArg_ParseTupleAndKeywords(args, kwds, "|O:foreach", kwlist, &py_policy) == false ) {
		return NULL;
	}

	as_error err;
	as_error_init(&err);

	TRACE();
	PyObject * py_results = PyList_New(0);
	
	TRACE();
	PyThreadState * _save = PyEval_SaveThread();
	
	TRACE();
    aerospike_query_foreach(self->client->as, &err, NULL, &self->query, each_result, py_results);
    
	TRACE();
	PyEval_RestoreThread(_save);
  	
	TRACE();
	if ( err.code != AEROSPIKE_OK ) {
		PyObject * py_err = NULL;
		error_to_pyobject(&err, &py_err);
		PyErr_SetObject(PyExc_Exception, py_err);
		TRACE();
		return NULL;
	}

	TRACE();
	return py_results;
}
Exemple #3
0
int
main(int argc, char* argv[])
{
	// Parse command line arguments.
	if (! example_get_opts(argc, argv, EXAMPLE_MULTI_KEY_OPTS)) {
		exit(-1);
	}

	// Connect to the aerospike database cluster.
	aerospike as;
	example_connect_to_aerospike_with_udf_config(&as, UDF_USER_PATH);

	// Start clean.
	example_remove_test_records(&as);
	example_remove_index(&as, TEST_INDEX_NAME);

	// Register the UDF in the database cluster.
	if (! example_register_udf(&as, UDF_FILE_PATH)) {
		example_cleanup(&as);
		exit(-1);
	}

	// Create a numeric secondary index on test-bin.
	if (! example_create_integer_index(&as, "test-bin", TEST_INDEX_NAME)) {
		cleanup(&as);
		exit(-1);
	}

	if (! insert_records(&as)) {
		cleanup(&as);
		exit(-1);
	}

	if (! example_read_test_records(&as)) {
		cleanup(&as);
		exit(-1);
	}

	as_error err;

	// Create an as_query object.
	as_query query;
	as_query_init(&query, g_namespace, g_set);

	// Generate an as_query.where condition. Note that as_query_destroy() takes
	// care of destroying all the query's member objects if necessary. However
	// using as_query_where_inita() does avoid internal heap usage.
	as_query_where_inita(&query, 1);
	as_query_where(&query, "test-bin", as_integer_range(1, 10));

	// Specify the UDF to use on the resulting stream.
	as_query_apply(&query, UDF_MODULE, "sum_test_bin", NULL);

	LOG("executing map-reduce query: where test-bin = 1 ... 10");

	// Execute the query. This call blocks - callbacks are made in the scope of
	// this call.
	if (aerospike_query_foreach(&as, &err, NULL, &query, query_cb, NULL) !=
			AEROSPIKE_OK) {
		LOG("aerospike_query_foreach() returned %d - %s", err.code,
				err.message);
		as_query_destroy(&query);
		cleanup(&as);
		exit(-1);
	}

	LOG("map-reduce query executed");

	// Reuse the as_query object for another query.
	as_query_destroy(&query);
	as_query_init(&query, g_namespace, g_set);

	// Generate an as_query.where condition.
	as_query_where_inita(&query, 1);
	as_query_where(&query, "test-bin", as_integer_range(1, 10));

	// Specify another UDF to use on the resulting stream. Like the previous UDF
	// it sums the test-bin values that satisfy the where condition, but does so
	// in a different, more efficient manner (see query_udf.lua).
	as_query_apply(&query, UDF_MODULE, "sum_test_bin_2", NULL);

	LOG("executing aggregate-reduce query: where test-bin = 1 ... 10");

	// Execute the query. This call blocks - callbacks are made in the scope of
	// this call.
	if (aerospike_query_foreach(&as, &err, NULL, &query, query_cb, NULL) !=
			AEROSPIKE_OK) {
		LOG("aerospike_query_foreach() returned %d - %s", err.code,
				err.message);
		as_query_destroy(&query);
		cleanup(&as);
		exit(-1);
	}

	LOG("aggregate-reduce query executed");

	// Reuse the as_query object for another query.
	as_query_destroy(&query);
	as_query_init(&query, g_namespace, g_set);

	// Generate an as_query.where condition.
	as_query_where_inita(&query, 1);
	as_query_where(&query, "test-bin", as_integer_range(1, 10));

	// Specify another UDF to use on the resulting stream. Like the previous
	// UDFs it sums test-bin values that satisfy the where condition, but first
	// applies a filter to sum only even values (see query_udf.lua).
	as_query_apply(&query, UDF_MODULE, "sum_test_bin_even", NULL);

	LOG("executing filter-aggregate-reduce query: where test-bin = 1 ... 10");

	// Execute the query. This call blocks - callbacks are made in the scope of
	// this call.
	if (aerospike_query_foreach(&as, &err, NULL, &query, query_cb, NULL) !=
			AEROSPIKE_OK) {
		LOG("aerospike_query_foreach() returned %d - %s", err.code,
				err.message);
		as_query_destroy(&query);
		cleanup(&as);
		exit(-1);
	}

	LOG("filter-aggregate-reduce query executed");

	// Reuse the as_query object for another query.
	as_query_destroy(&query);
	as_query_init(&query, g_namespace, g_set);

	// No as_query.where condition in this case, so we include everything.

	// Specify another UDF to use on the resulting stream. This UDF operates on
	// the numbers-bin (string) values, and demonstrates a case where the value
	// returned by the query callback is an as_map (instead of an as_integer).
	as_query_apply(&query, UDF_MODULE, "count_numbers", NULL);

	LOG("executing numbers aggregate-reduce query: all records");

	// Execute the query. This call blocks - callbacks are made in the scope of
	// this call.
	if (aerospike_query_foreach(&as, &err, NULL, &query, query_cb_map, NULL) !=
			AEROSPIKE_OK) {
		LOG("aerospike_query_foreach() returned %d - %s", err.code,
				err.message);
		as_query_destroy(&query);
		cleanup(&as);
		exit(-1);
	}

	LOG("numbers aggregate-reduce query executed");

	as_query_destroy(&query);

	// Cleanup and disconnect from the database cluster.
	cleanup(&as);

	LOG("aggregate query example successfully completed");

	return 0;
}
int
main(int argc, char* argv[])
{
	// Parse command line arguments.
	if (! example_get_opts(argc, argv, EXAMPLE_MULTI_KEY_OPTS)) {
		exit(-1);
	}

	// Connect to the aerospike database cluster.
	aerospike as;
	example_connect_to_aerospike(&as);

	// Ensure the server supports geospatial queries.
	if (! aerospike_has_geo(&as)) {
		fprintf(stderr, "server does not support geospatial\n");
		exit(0);
	}
	
	// Start clean.
	example_remove_test_records(&as);
	example_remove_index(&as, TEST_INDEX_NAME);

	// Create a numeric secondary index on test-bin.
	if (! example_create_2dsphere_index(&as, TEST_BIN_NAME, TEST_INDEX_NAME)) {
		cleanup(&as);
		exit(-1);
	}

	if (! insert_records(&as)) {
		cleanup(&as);
		exit(-1);
	}

	as_error err;

	// Create an as_query object.
	as_query query;
	as_query_init(&query, g_namespace, g_set);

	// Our query region:
	char const * region =
		"{ "
		"    \"type\": \"Polygon\", "
		"    \"coordinates\": [ "
		"        [[-122.500000, 37.000000],[-121.000000, 37.000000], "
		"         [-121.000000, 38.080000],[-122.500000, 38.080000], "
		"         [-122.500000, 37.000000]] "
		"    ] "
		" } ";

	// Generate an as_query.where condition. Note that as_query_destroy() takes
	// care of destroying all the query's member objects if necessary. However
	// using as_query_where_inita() does avoid internal heap usage.
	as_query_where_inita(&query, 1);
	as_query_where(&query, TEST_BIN_NAME, as_geo_within(region));

	LOG("executing query: within <rect>");

	// Execute the query. This call blocks - callbacks are made in the scope of
	// this call.
	if (aerospike_query_foreach(&as, &err, NULL, &query, query_cb, NULL) !=
			AEROSPIKE_OK) {
		LOG("aerospike_query_foreach() returned %d - %s", err.code,
				err.message);
		as_query_destroy(&query);
		cleanup(&as);
		exit(-1);
	}

	LOG("query executed");

	as_query_destroy(&query);

	// Cleanup and disconnect from the database cluster.
	cleanup(&as);

	LOG("simple query example successfully completed");

	return 0;
}
PyObject * AerospikeQuery_Foreach(AerospikeQuery * self, PyObject * args, PyObject * kwds)
{
	// Python Function Arguments
	PyObject * py_callback = NULL;
	PyObject * py_policy = NULL;

	// Python Function Keyword Arguments
	static char * kwlist[] = {"callback", "policy", NULL};

	// Python Function Argument Parsing
	if ( PyArg_ParseTupleAndKeywords(args, kwds, "O|O:foreach", kwlist, &py_callback, &py_policy) == false ) {
		as_query_destroy(&self->query);
		return NULL;
	}

	// Initialize callback user data
	LocalData data;
	data.callback = py_callback;
	as_error_init(&data.error);

	// Aerospike Client Arguments
	as_error err;
	as_policy_query query_policy;
	as_policy_query * query_policy_p = NULL;

	// Initialize error
	as_error_init(&err);

	if (!self || !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_exists
	pyobject_to_policy_query(&err, py_policy, &query_policy, &query_policy_p,
			&self->client->as->config.policies.query);
	if ( err.code != AEROSPIKE_OK ) {
		goto CLEANUP;
	}

	// We are spawning multiple threads
	PyThreadState * _save = PyEval_SaveThread();

	// Invoke operation
	aerospike_query_foreach(self->client->as, &err, query_policy_p, &self->query, each_result, &data);

	// We are done using multiple threads
	PyEval_RestoreThread(_save);
	if (data.error.code != AEROSPIKE_OK) {
		goto CLEANUP;
	}

CLEANUP:
	if ( self->query.apply.arglist ){
		as_arraylist_destroy( (as_arraylist *) self->query.apply.arglist );
	}
	self->query.apply.arglist = NULL;

	if ( err.code != AEROSPIKE_OK || data.error.code != AEROSPIKE_OK ) {
		PyObject * py_err = NULL;
		if ( err.code != AEROSPIKE_OK ){
			error_to_pyobject(&err, &py_err);
		}
		if ( data.error.code != AEROSPIKE_OK ){
			error_to_pyobject(&data.error, &py_err);
		}
		PyErr_SetObject(PyExc_Exception, py_err);
		Py_DECREF(py_err);
		return NULL;
	}

	Py_INCREF(Py_None);
	return Py_None;
}
int
main(int argc, char* argv[])
{
	// Parse command line arguments.
	if (! example_get_opts(argc, argv, EXAMPLE_MULTI_KEY_OPTS)) {
		exit(-1);
	}

	// Connect to the aerospike database cluster.
	aerospike as;
	example_connect_to_aerospike(&as);

	// Start clean.
	example_remove_test_records(&as);
	example_remove_index(&as, TEST_INDEX_NAME);

	// Create a numeric secondary index on test-bin.
	if (! example_create_integer_index(&as, "test-bin", TEST_INDEX_NAME)) {
		cleanup(&as);
		exit(-1);
	}

	if (! insert_records(&as)) {
		cleanup(&as);
		exit(-1);
	}

	if (! example_read_test_records(&as)) {
		cleanup(&as);
		exit(-1);
	}

	as_error err;

	// Create an as_query object.
	as_query query;
	as_query_init(&query, g_namespace, g_set);

	// Generate an as_query.where condition. Note that as_query_destroy() takes
	// care of destroying all the query's member objects if necessary. However
	// using as_query_where_inita() does avoid internal heap usage.
	as_query_where_inita(&query, 1);
	as_query_where(&query, "test-bin", as_integer_equals(7));

	LOG("executing query: where test-bin = 7");

	// Execute the query. This call blocks - callbacks are made in the scope of
	// this call.
	if (aerospike_query_foreach(&as, &err, NULL, &query, query_cb, NULL) !=
			AEROSPIKE_OK) {
		LOG("aerospike_query_foreach() returned %d - %s", err.code,
				err.message);
		as_query_destroy(&query);
		cleanup(&as);
		exit(-1);
	}

	LOG("query executed");

	as_query_destroy(&query);

	// Cleanup and disconnect from the database cluster.
	cleanup(&as);

	LOG("simple query example successfully completed");

	return 0;
}