/**
 * Execute a query and call the callback function for each result item.
 *
 * @param as        - the aerospike cluster to connect to.
 * @param err       - the error is populated if the return value is not AEROSPIKE_OK.
 * @param policy    - the policy to use for this operation. If NULL, then the default policy will be used.
 * @param query     - the query to execute against the cluster
 * @param udata     - user-data to be passed to the callback
 * @param callback  - the callback function to call for each result item.
 *
 * @return AEROSPIKE_OK on success, otherwise an error.
 */
as_status aerospike_query_foreach(
	aerospike * as, as_error * err, const as_policy_query * policy, 
	const as_query * query, 
	aerospike_query_foreach_callback callback, void * udata) 
{
	// we want to reset the error so, we have a clean state
	as_error_reset(err);
	
	// resolve policies
	// as_policy_query p;
	// as_policy_query_resolve(&p, &as->config.policies, policy);
	
	if ( aerospike_query_init(as, err) != AEROSPIKE_OK ) {
		return err->code;
	}

	cl_query * clquery = as_query_toclquery(query);

	clquery_bridge bridge = {
		.udata = udata,
		.callback = callback
	};

	cl_rv rc = citrusleaf_query_foreach(as->cluster, clquery, &bridge, clquery_callback);

	cl_query_destroy(clquery);

	return as_error_fromrc(err, rc);
}
/**
 * Execute a query and call the callback function for each result item.
 *
 * @param as        - the aerospike cluster to connect to.
 * @param err       - the error is populated if the return value is not AEROSPIKE_OK.
 * @param policy    - the policy to use for this operation. If NULL, then the default policy will be used.
 * @param query     - the query to execute against the cluster
 * @param udata     - user-data to be passed to the callback
 * @param callback  - the callback function to call for each result item.
 *
 * @return AEROSPIKE_OK on success, otherwise an error.
 */
as_status aerospike_query_foreach(
	aerospike * as, as_error * err, const as_policy_query * policy, 
	const as_query * query, 
	aerospike_query_foreach_callback callback, void * udata) 
{
	// we want to reset the error so, we have a clean state
	as_error_reset(err);
    as_val *  err_val = NULL;
	
	// resolve policies
	// as_policy_query p;
	// as_policy_query_resolve(&p, &as->config.policies, policy);
	
	if ( aerospike_query_init(as, err) != AEROSPIKE_OK ) {
		return err->code;
	}

	cl_query * clquery = as_query_toclquery(query);

	clquery_bridge bridge = {
		.udata = udata,
		.callback = callback
	};
	cl_rv rc = citrusleaf_query_foreach(as->cluster, clquery, &bridge, clquery_callback, &err_val);
    as_status ret = as_error_fromrc(err, rc);

    if (CITRUSLEAF_OK != rc && err_val) {
        char * err_str = as_val_tostring(err_val);
        if(err_str) {
            strncat(err->message," : ",sizeof(err->message) - strlen(err->message));
            strncat(err->message,err_str,sizeof(err->message) - strlen(err->message));
            cf_free(err_str);
        }
        as_val_destroy(err_val);
    }
	cl_query_destroy(clquery);
	return ret;
}