Example #1
0
void* as_ldt_store_args(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    DEBUG_TRACE("begin args");

    ldt_store_args_t* args = (ldt_store_args_t*)enif_alloc(sizeof(ldt_store_args_t));

    // ns, set, key
    if (!init_key_from_args(env, &args->key, argv)) goto error0;

    // ldt
    if (!init_ldt_from_arg(env, &args->ldt, AS_LDT_LSET, argv[3])) goto error1;

    // timeout
    if (!init_policy_apply_from_arg(env, &args->policy, argv[4])) goto error2;

    // value
    if (!(args->p_value=new_val_from_arg(env, argv[5]))) goto error3;

    DEBUG_TRACE("end args");

    return args;

    error3:
    error2:
    as_ldt_destroy(&args->ldt);
    error1:
    as_key_destroy(&args->key);
    error0:
    enif_free(args);

    return NULL;
}
Example #2
0
void as_ldt_clean_store_args(ErlNifEnv* env, ldt_store_args_t* args)
{
    DEBUG_TRACE("begin clean args");
    as_val_destroy(args->p_value);
    as_ldt_destroy(&args->ldt);
    as_key_destroy(&args->key);
    DEBUG_TRACE("end clean args");
}
/*
 *******************************************************************************************************
 * Wrapper function to perform an aerospike_key_exists within the C client.
 *
 * @param as_object_p           The C client's aerospike object.
 * @param as_key_p              The C client's as_key that identifies the record.
 * @param metadata_p            The return metadata for the exists/getMetadata API to be 
 *                              populated by this function.
 * @param options_p             The user's optional policy options to be used if set, else defaults.
 * @param error_p               The as_error to be populated by the function
 *                              with the encountered error if any.
 *
 *******************************************************************************************************
 */
extern as_status 
aerospike_php_exists_metadata(aerospike* as_object_p, 
                              zval* key_record_p, 
                              zval* metadata_p, 
                              zval* options_p,
                              as_error* error_p) {

    as_status              status = AEROSPIKE_OK;
    as_key                 as_key_for_put_record;
    int16_t                initializeKey = 0;

    if ((!as_object_p) || (!key_record_p)) {
        status = AEROSPIKE_ERR;
        goto exit;
    }

    if (PHP_TYPE_ISNOTARR(key_record_p) ||
             ((options_p) && (PHP_TYPE_ISNOTARR(options_p)))) {
        status = AEROSPIKE_ERR_PARAM;
        DEBUG_PHP_EXT_ERROR("input parameters (type) for exist/getMetdata function not proper.");
        goto exit;
    }

    if (PHP_TYPE_ISNOTARR(metadata_p)) {
        zval*         metadata_arr_p = NULL;

        MAKE_STD_ZVAL(metadata_arr_p);
        array_init(metadata_arr_p);
        ZVAL_ZVAL(metadata_p, metadata_arr_p, 1, 1);
    }

    if (AEROSPIKE_OK != (status =
                aerospike_transform_iterate_for_rec_key_params(Z_ARRVAL_P(key_record_p),
                    &as_key_for_put_record, &initializeKey))) {
        DEBUG_PHP_EXT_ERROR("unable to iterate through exists/getMetadata key params");
        goto exit;
    }

    if (AEROSPIKE_OK != (status =
                aerospike_record_operations_exists(as_object_p, &as_key_for_put_record,
                    error_p, metadata_p, options_p))) {
        DEBUG_PHP_EXT_ERROR("exists/getMetadata: unable to fetch the record");
        goto exit;
    }

exit:
    if (initializeKey) {
        as_key_destroy(&as_key_for_put_record);
    }

    return status;
}
Example #4
0
static int put(lua_State *L){

	//Cluster
	aerospike* as = lua_touserdata(L, 1);

	//Namespace
	const char* nameSpace = luaL_checkstring(L, 2);

	//Set
	const char* set = luaL_checkstring(L, 3);

	//Key as string
	const char* keyString = luaL_checkstring(L, 4);

	// Number of bins.
	const int numBins = lua_tointeger(L, 5);

	//Bins
	as_record rec = add_bins_to_rec(L, 6, numBins);

	//const as_record * test = &rec;
	//if (as_val_type(as_record_get(test, "animals")) == AS_LIST)
	//	printf("correct list\n");
	//else
	//	printf("not a list\n");

	// Create key
	as_key key;
	as_error err;
	as_key_init(&key, nameSpace, set, keyString);

	// Write record
	aerospike_key_put(as, &err, NULL, &key, &rec);
	as_key_destroy(&key);
    as_record_destroy(&rec);
	// Return status
	lua_pushnumber(L, err.code);
	lua_pushstring(L, err.message);
	return 2;

}
static void insert_data(int numrecs, const char *setname)
{
	as_status rc;
	char strval[SET_STRSZ], strkey[SET_STRSZ];

	as_error err;
	as_error_reset(&err);

	for (int i=0; i<numrecs; i++) {

		sprintf(strval, "str-%s-%d", setname ? setname : "noset", i);
		sprintf(strkey, "key-%s-%d", setname, i);

		// Map bin
        as_hashmap m;
        as_hashmap_init(&m, 8);
		as_stringmap_set_int64((as_map *) &m, "x", i);
		as_stringmap_set_int64((as_map *) &m, "y", i+1);
		as_stringmap_set_int64((as_map *) &m, "z", i+2);

        as_record r;
        as_record_init(&r, 3);
		as_record_set_int64(&r, "bin1", i);
		as_record_set_str(&r, "bin2", strval);
		as_record_set_map(&r, "bin3", (as_map *) &m);

        as_key k;
		as_key_init(&k, NS, setname, strkey);

		rc = aerospike_key_put(as, &err, NULL, &k, &r);
		if (rc != AEROSPIKE_OK) {
			error("digest put failed with error %d", rc);
		}

        as_hashmap_destroy(&m);
		as_key_destroy(&k);
        as_record_destroy(&r);
	}

}
Example #6
0
static int increment(lua_State *L){
	as_error err;
	aerospike* as = lua_touserdata(L, 1);
	const char* nameSpace = luaL_checkstring(L, 2);
	const char* set = luaL_checkstring(L, 3);
	const char* keyString = luaL_checkstring(L, 4);
	const int numBins = lua_tointeger(L, 5);

	as_operations ops = add_bins_to_increment(L, 6, numBins);

	as_key key;
	as_key_init(&key, nameSpace, set, keyString);
	// Apply the operations. Since the record does not exist, it will be created
	// and the bins initialized with the ops' integer values.
	aerospike_key_operate(as, &err, NULL, &key, &ops, NULL);

	as_operations_destroy(&ops);
	as_key_destroy(&key);

	lua_pushnumber(L, err.code);
	lua_pushstring(L, err.message);
	return 2;
}
Example #7
0
/**
 *	Destroy the batch of keys.
 */
void as_batch_destroy(as_batch * batch)
{
	if ( !batch ) return;

	if ( batch->keys.entries ) {

		for (int i = 0; i < batch->keys.size; i++ ) {
			as_key_destroy(&batch->keys.entries[i]);
		}

		if ( batch->keys._free ) {
			free(batch->keys.entries);
		}

		batch->keys._free = false;
		batch->keys.size = 0;
		batch->keys.entries = NULL;
	}

	if ( batch->_free ) {
		free(batch);
	}
}
Example #8
0
void* as_ldt_get_args(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    ldt_get_args_t* args = (ldt_get_args_t*)enif_alloc(sizeof(ldt_get_args_t));

    // ns, set, key
    if (!init_key_from_args(env, &args->key, argv)) goto error0;

    // ldt
    if (!init_ldt_from_arg(env, &args->ldt, AS_LDT_LSET, argv[3])) goto error1;

    // policy
    if (!init_policy_apply_from_arg(env, &args->policy, argv[4])) goto error2;

    return args;

    error2:
    as_ldt_destroy(&args->ldt);
    error1:
    as_key_destroy(&args->key);
    error0:
    enif_free(args);

    return NULL;
}
/**
 *******************************************************************************************************
 * This function invokes csdk's API's.
 *
 * @param self                  AerospikeClient object
 * @param err                   The as_error to be populated by the function
 *                              with the encountered error if any.
 * @param key                   The C client's as_key that identifies the record.
 * @param py_list               The list containing op, bin and value.
 * @param py_meta               The metadata for the operation.
 * @param operate_policy_p      The value for operate policy.
 *******************************************************************************************************
 */
static
PyObject *  AerospikeClient_Operate_Invoke(
	AerospikeClient * self, as_error *err,
	as_key * key, PyObject * py_list, PyObject * py_meta,
	as_policy_operate * operate_policy_p)
{
	as_val* put_val = NULL;
	char* bin = NULL;
	char* val = NULL;
	long offset = 0;
    double double_offset = 0.0;
	uint32_t ttl = 0;
	long operation = 0;
	int i = 0;
	PyObject * py_rec = NULL;
	PyObject * py_ustr = NULL;
	PyObject * py_ustr1 = NULL;
	PyObject * py_bin = NULL;
	as_record * rec = NULL;

	as_static_pool static_pool;
	memset(&static_pool, 0, sizeof(static_pool));

	as_operations ops;
	Py_ssize_t size = PyList_Size(py_list);
	as_operations_inita(&ops, size);

	if (!self || !self->as) {
		as_error_update(err, AEROSPIKE_ERR_PARAM, "Invalid aerospike object");
		goto CLEANUP;
	}

	if(py_meta) {
		AerospikeClient_CheckForMeta(py_meta, &ops, err);
	}

	if (err->code != AEROSPIKE_OK) {
		goto CLEANUP;
	}

	for ( i = 0; i < size; i++) {
		PyObject * py_val = PyList_GetItem(py_list, i);
		operation = -1;
		offset = 0;
        double_offset = 0.0;
		if ( PyDict_Check(py_val) ) {
			PyObject *key_op = NULL, *value = NULL;
			PyObject * py_value = NULL;
			Py_ssize_t pos = 0;
			while (PyDict_Next(py_val, &pos, &key_op, &value)) {
				if ( ! PyString_Check(key_op) ) {
					as_error_update(err, AEROSPIKE_ERR_CLIENT, "A operation key must be a string.");
					goto CLEANUP;
				} else {
					char * name = PyString_AsString(key_op);
					if(!strcmp(name,"op") && (PyInt_Check(value) || PyLong_Check(value))) {
						operation = PyInt_AsLong(value);
					} else if (!strcmp(name, "bin")) {
						py_bin = value;
					} else if(!strcmp(name, "val")) {
						py_value = value;
					} else {
						as_error_update(err, AEROSPIKE_ERR_PARAM, "operation can contain only op, bin and val keys");
						goto CLEANUP;
					}
				}
			}

			if (py_bin) {
				if (PyUnicode_Check(py_bin)) {
					py_ustr = PyUnicode_AsUTF8String(py_bin);
					bin = PyString_AsString(py_ustr);
				} else if (PyString_Check(py_bin)) {
					bin = PyString_AsString(py_bin);
				} else {
					as_error_update(err, AEROSPIKE_ERR_PARAM, "Bin name should be of type string");
					goto CLEANUP;
				}
			} else if (!py_bin && operation != AS_OPERATOR_TOUCH) {
				as_error_update(err, AEROSPIKE_ERR_PARAM, "Bin is not given");
				goto CLEANUP;
			}
			if (py_value) {
				if (check_type(self, py_value, operation, err)) {
                    goto CLEANUP;
				} else if (PyString_Check(py_value) && (operation == AS_OPERATOR_INCR)) {
                    char * incr_string = PyString_AsString(py_value);
                    int incr_value = 0, sign = 1;

                    if (strlen(incr_string) > 15) {
				        as_error_update(err, AEROSPIKE_ERR_PARAM, "Unsupported string length for increment operation");
                        goto CLEANUP;
                    }
                    if (*incr_string == '-') {
                        incr_string = incr_string + 1;
                        sign = -1;
                    } else if (*incr_string == '+') {
                        incr_string = incr_string + 1;
                        sign = 1;
                    }
                    while (*incr_string != '\0') {
                        if (*incr_string >= 48 && *incr_string <= 57) {
                            incr_value = (incr_value * 10) + (*incr_string ^ 0x30);
                        } else {
				            as_error_update(err, AEROSPIKE_ERR_PARAM, "Unsupported operand type(s) for +: 'int' and 'str'");
                            goto CLEANUP;
                        }
                        incr_string = incr_string + 1;
                    }
                    incr_value = incr_value * sign;
                    py_value = PyInt_FromLong(incr_value);
                }
			} else if ((!py_value) && (operation != AS_OPERATOR_READ)) {
				as_error_update(err, AEROSPIKE_ERR_PARAM, "Value should be given");
				goto CLEANUP;
			}

			switch(operation) {
				case AS_OPERATOR_APPEND:
					if (PyUnicode_Check(py_value)) {
						py_ustr1 = PyUnicode_AsUTF8String(py_value);
						val = PyString_AsString(py_ustr1);
					} else {
						val = PyString_AsString(py_value);
					}
					as_operations_add_append_str(&ops, bin, val);
					break;
				case AS_OPERATOR_PREPEND:
					if (PyUnicode_Check(py_value)) {
						py_ustr1 = PyUnicode_AsUTF8String(py_value);
						val = PyString_AsString(py_ustr1);
					} else {
						val = PyString_AsString(py_value);
					}
					as_operations_add_prepend_str(&ops, bin, val);
					break;
				case AS_OPERATOR_INCR:
					if (PyInt_Check(py_value)) {
                        offset = PyInt_AsLong(py_value);
                        as_operations_add_incr(&ops, bin, offset);
                    } else if ( PyLong_Check(py_value) ) {
                        offset = PyLong_AsLong(py_value);
                        if(-1 == offset) {
                            as_error_update(err, AEROSPIKE_ERR_PARAM, "integer value exceeds sys.maxsize");
                            goto CLEANUP;
                        }
                        as_operations_add_incr(&ops, bin, offset);
                    } else if (PyFloat_Check(py_value)) {
                        double_offset = PyFloat_AsDouble(py_value);
                        as_operations_add_incr_double(&ops, bin, double_offset);
                    }
                    break;
				case AS_OPERATOR_TOUCH:
					if (PyInt_Check(py_value)) {
                        ops.ttl = PyInt_AsLong(py_value);
                    } else if ( PyLong_Check(py_value) ) {
                        ttl = PyLong_AsLong(py_value);
                        if((uint32_t)-1 == ttl) {
                            as_error_update(err, AEROSPIKE_ERR_PARAM, "integer value for ttl exceeds sys.maxsize");
                            goto CLEANUP;
                        }
                        ops.ttl = ttl;
                    }
					as_operations_add_touch(&ops);
					break;
				case AS_OPERATOR_READ:
					as_operations_add_read(&ops, bin);
					break;
				case AS_OPERATOR_WRITE:
					pyobject_to_astype_write(self, err, bin, py_value, &put_val, &ops,
							&static_pool, SERIALIZER_PYTHON);
					if (err->code != AEROSPIKE_OK) {
						goto CLEANUP;
					}
					as_operations_add_write(&ops, bin, (as_bin_value *) put_val);
					break;
				default:
					as_error_update(err, AEROSPIKE_ERR_PARAM, "Invalid operation given");
			}
		}
	}

	// Initialize record
	as_record_init(rec, 0);

	aerospike_key_operate(self->as, err, operate_policy_p, key, &ops, &rec);
	if (err->code != AEROSPIKE_OK) {
		as_error_update(err, err->code, NULL);
		goto CLEANUP;
	}
	if(rec) {
		record_to_pyobject(err, rec, key, &py_rec);
	}

CLEANUP:
	if (py_ustr) {
		Py_DECREF(py_ustr);
	}
	if (py_ustr1) {
		Py_DECREF(py_ustr1);
	}
	if (rec) {
		as_record_destroy(rec);
	}
	if (key->valuep) {
		as_key_destroy(key);
	}
	if (put_val) {
		as_val_destroy(put_val);
	}

	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;
	}

	if (py_rec) {
		return py_rec;
	} else {
		return PyLong_FromLong(0);
	}
}
/**
 *******************************************************************************************************
 * This function invokes csdk's API to remove particular record.
 *
 * @param self                  AerospikeClient object
 * @param py_key                The key under which to store the record
 * @param generation            The generation value
 * @param py_policy             The optional policy parameters
 *
 * Returns 0 on success.
 * In case of error,appropriate exceptions will be raised.
 *******************************************************************************************************
 */
PyObject * AerospikeClient_Remove_Invoke(
		AerospikeClient * self,
		PyObject * py_key, PyObject * py_meta, PyObject * py_policy)
{

	// Aerospike Client Arguments
	as_error err;
	as_policy_remove remove_policy;
	as_policy_remove * remove_policy_p = NULL;
	as_key key;

	// Initialisation flags
	bool key_initialised = false;

	// Initialize error
	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;
	}

	// Convert python key object to as_key
	pyobject_to_key(&err, py_key, &key);
	if ( err.code != AEROSPIKE_OK ) {
		goto CLEANUP;
	}
	// Key is initialised successfully
	key_initialised = true;

	// Convert python policy object to as_policy_exists
	if (py_policy) {
		pyobject_to_policy_remove(&err, py_policy, &remove_policy, &remove_policy_p,
				&self->as->config.policies.remove);
		if ( err.code != AEROSPIKE_OK ) {
			goto CLEANUP;
		} else {
			if ( py_meta && PyDict_Check(py_meta) ) {
				PyObject * py_gen = PyDict_GetItemString(py_meta, "gen");

				if( py_gen != NULL ){
					if ( PyInt_Check(py_gen) ) {
						remove_policy_p->generation = (uint16_t) PyInt_AsLong(py_gen);
					} else if ( PyLong_Check(py_gen) ) {
						remove_policy_p->generation = (uint16_t) PyLong_AsLongLong(py_gen);
                        if((uint16_t)-1 == remove_policy_p->generation) {
						    as_error_update(&err, AEROSPIKE_ERR_PARAM, "integer value for gen exceeds sys.maxsize");
			                goto CLEANUP;
                        }
					} else {
						as_error_update(&err, AEROSPIKE_ERR_PARAM, "Generation should be an int or long");
					}
				}
			}
		}
	}

	// Invoke operation
    Py_BEGIN_ALLOW_THREADS
	aerospike_key_remove(self->as, &err, remove_policy_p, &key);
    Py_END_ALLOW_THREADS
	if(err.code != AEROSPIKE_OK) {
		as_error_update(&err, err.code, NULL);
	}

CLEANUP:

	if (key_initialised == true){
		// Destroy the key if it is initialised successfully.
		as_key_destroy(&key);
	}

	if ( err.code != AEROSPIKE_OK ) {
		PyObject * py_err = NULL;
		error_to_pyobject(&err, &py_err);
		PyObject *exception_type = raise_exception(&err);
		if(PyObject_HasAttrString(exception_type, "key")) {
			PyObject_SetAttrString(exception_type, "key", py_key);
		} 
		if(PyObject_HasAttrString(exception_type, "bin")) {
			PyObject_SetAttrString(exception_type, "bin", Py_None);
		}
		PyErr_SetObject(exception_type, py_err);
		Py_DECREF(py_err);
		return NULL;
	}

	return PyLong_FromLong(0);
}
/**
 *******************************************************************************************************
 * This function applies a registered udf module on a particular record.
 *
 * @param self                  AerospikeClient object
 * @param py_key                The key under which to store the record.
 * @param py_module             The module name.
 * @param py_function           The UDF function to be applied on a record.
 * @param py_arglist            The arguments to the UDF function
 * @param py_policy             The optional policy parameters
 *
 * Returns the result of UDF function.
 *******************************************************************************************************
 */
PyObject * AerospikeClient_Apply_Invoke(
    AerospikeClient * self,
    PyObject * py_key, PyObject * py_module, PyObject * py_function,
    PyObject * py_arglist, PyObject * py_policy)
{
    // Python Return Value
    PyObject * py_result = NULL;

    // Aerospike Client Arguments
    as_error err;
    as_policy_apply apply_policy;
    as_policy_apply * apply_policy_p = NULL;
    as_key key;
    char * module = NULL;
    char * function = NULL;
    as_list * arglist = NULL;
    as_val * result = NULL;

    PyObject * py_umodule   = NULL;
    PyObject * py_ufunction = NULL;

    // Initialisation flags
    bool key_initialised = false;

    // Initialize error
    as_error_init(&err);

    if( !PyList_Check(py_arglist) ) {
        PyErr_SetString(PyExc_TypeError, "expected UDF method arguments in a 'list'");
        return NULL;
    }

    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;
    }

    // Convert python key object to as_key
    pyobject_to_key(&err, py_key, &key);
    if ( err.code != AEROSPIKE_OK ) {
        goto CLEANUP;
    }
    // Key is initialiased successfully
    key_initialised = true;

    // Convert python list to as_list
    pyobject_to_list(self, &err, py_arglist, &arglist, NULL, -1);
    if ( err.code != AEROSPIKE_OK ) {
        goto CLEANUP;
    }

    // Convert python policy object to as_policy_apply
    pyobject_to_policy_apply(&err, py_policy, &apply_policy, &apply_policy_p,
                             &self->as->config.policies.apply);
    if ( err.code != AEROSPIKE_OK ) {
        goto CLEANUP;
    }

    if ( PyUnicode_Check(py_module) ) {
        py_umodule = PyUnicode_AsUTF8String(py_module);
        module = PyStr_AsString(py_umodule);
    }
    else if ( PyStr_Check(py_module) ) {
        module = PyStr_AsString(py_module);
    }
    else {
        as_error_update(&err, AEROSPIKE_ERR_CLIENT, "udf module argument must be a string or unicode string");
        goto CLEANUP;
    }

    if ( PyUnicode_Check(py_function) ) {
        py_ufunction = PyUnicode_AsUTF8String(py_function);
        function = PyStr_AsString(py_ufunction);
    }
    else if ( PyStr_Check(py_function) ) {
        function = PyStr_AsString(py_function);
    }
    else {
        as_error_update(&err, AEROSPIKE_ERR_CLIENT, "function name must be a string or unicode string");
        goto CLEANUP;
    }

    // Invoke operation
    aerospike_key_apply(self->as, &err, apply_policy_p, &key, module, function, arglist, &result);

    if ( err.code == AEROSPIKE_OK ) {
        val_to_pyobject(&err, result, &py_result);
    } else {
        as_error_update(&err, err.code, NULL);
    }

CLEANUP:

    if (py_umodule) {
        Py_DECREF(py_umodule);
    }

    if (py_ufunction) {
        Py_DECREF(py_ufunction);
    }

    if (key_initialised == true) {
        // Destroy the key if it is initialised successfully.
        as_key_destroy(&key);
    }
    as_list_destroy(arglist);
    as_val_destroy(result);

    if ( err.code != AEROSPIKE_OK ) {
        PyObject * py_err = NULL;
        error_to_pyobject(&err, &py_err);
        PyObject *exception_type = raise_exception(&err);
        if(PyObject_HasAttrString(exception_type, "key")) {
            PyObject_SetAttrString(exception_type, "key", py_key);
        }
        if(PyObject_HasAttrString(exception_type, "bin")) {
            PyObject_SetAttrString(exception_type, "bin", Py_None);
        }
        if(PyObject_HasAttrString(exception_type, "module")) {
            PyObject_SetAttrString(exception_type, "module", py_module);
        }
        if(PyObject_HasAttrString(exception_type, "func")) {
            PyObject_SetAttrString(exception_type, "func", py_function);
        }
        PyErr_SetObject(exception_type, py_err);
        Py_DECREF(py_err);
        return NULL;
    }

    return py_result;
}
/**
 * Creates 100 records and 9 indexes.
 *
 * Records are structured as:
 *      {a: String, b: Integer, c: Integer, d: Integer, e: Integer}
 *
 * The key is "a-b-c-d-e"
 *
 * The values are:
 *      a = "abc"
 *      b = 100
 *      c = <current index>
 *      d = c % 10
 *      e = b + (c + 1) * (d + 1) / 2
 */
bool query_foreach_create()
{
	as_error err;
	as_error_reset(&err);
	
	int n_recs = 100;
	
	as_status status;
	as_index_task task;
	
	// create index on "a"	
	status = aerospike_index_create(as, &err, &task, NULL, NAMESPACE, SET, "a", "idx_test_a", AS_INDEX_STRING);
	index_process_return_code(status, &err, &task);

	// create index on "b"
	status = aerospike_index_create(as, &err, &task, NULL, NAMESPACE, SET, "b", "idx_test_b", AS_INDEX_NUMERIC);
	index_process_return_code(status, &err, &task);

	// create index on "c"
	status = aerospike_index_create(as, &err, &task, NULL, NAMESPACE, SET, "c", "idx_test_c", AS_INDEX_NUMERIC);
	index_process_return_code(status, &err, &task);

	// create index on "d"
	status = aerospike_index_create(as, &err, &task, NULL, NAMESPACE, SET, "d", "idx_test_d", AS_INDEX_NUMERIC);
	index_process_return_code(status, &err, &task);

	// create complex index on "x"
	status = aerospike_index_create_complex(as, &err, &task, NULL, NAMESPACE, SET, "x", "idx_test_x", AS_INDEX_TYPE_LIST, AS_INDEX_STRING);
	index_process_return_code(status, &err, &task);

	// create complex index on "y"
	status = aerospike_index_create_complex(as, &err, &task, NULL, NAMESPACE, SET, "y", "idx_test_y", AS_INDEX_TYPE_MAPKEYS, AS_INDEX_STRING);
	index_process_return_code(status, &err, &task);

	// create complex index on "y"	 
	status = aerospike_index_create_complex(as, &err, &task, NULL, NAMESPACE, SET, "y", "idx_test_y1", AS_INDEX_TYPE_MAPVALUES, AS_INDEX_STRING);
	index_process_return_code(status, &err, &task);

	// create complex index on "z"	 
	status = aerospike_index_create_complex(as, &err, &task, NULL, NAMESPACE, SET, "z", "idx_test_z", AS_INDEX_TYPE_LIST, AS_INDEX_NUMERIC);
	index_process_return_code(status, &err, &task);

	char* buffer = alloca(n_recs * 1024 + 1);
	uint32_t the_ttl = AS_RECORD_NO_EXPIRE_TTL;
	
	// insert records
	for ( int i = 0; i < n_recs; i++ ) {

		if (i == 10) {
			// We change the TTL from never to 100 days
			the_ttl = 100 * 24 * 60 * 60;
		}
		else if (i == 42) {
			// NOTE - We pause on the 42nd iteration for a few
			// milliseconds and note the time.  We can then use the
			// as_predexp_rec_last_update_after predicate below to find
			// the later records.

			as_sleep(5);
			g_epochns = cf_clock_getabsolute() * 1000 * 1000;
			as_sleep(5);

			// Also on the 42nd iteration we change the TTL to
			// 10 days for the remaining records.
			the_ttl = 10 * 24 * 60 * 60;
		}
		
		char * 	a = "abc";
		int 	b = n_recs;
		int 	c = i;
		int 	d = i % 10;
		int 	e = b + (c + 1) * (d + 1) / 2;
		int		g = i;	// Only set on odd records.
		
		char f[64];
		snprintf(f, sizeof(f), "0x%04x", i);
		
		char keystr[64] = { '\0' };
		snprintf(keystr, 64, "%s-%d-%d-%d-%d", a, b, c, d, e);
		
		// Make list		
		as_arraylist list;
		as_arraylist_init(&list, 3, 0);
		if ( (i%3) == 0) {
			as_arraylist_append_str(&list, "x");
			as_arraylist_append_str(&list, "x1");
			as_arraylist_append_str(&list, "x2");
		} else {
			as_arraylist_append_str(&list, "not_x1");
			as_arraylist_append_str(&list, "not_x2");
			as_arraylist_append_str(&list, "not_x3");

		}
		
		// Make map
		as_hashmap map;
		as_hashmap_init(&map, 1);
		if ( (i%7) == 0) {
			as_stringmap_set_str((as_map *) &map, "ykey", "yvalue");
		} else {
			as_stringmap_set_str((as_map *) &map, "ykey_not", "yvalue_not");

		}		
		
		// Make list of integers		
		as_arraylist list2;
		as_arraylist_init(&list2, 5, 0);
		as_arraylist_append_int64(&list2, i);
		as_arraylist_append_int64(&list2, i+1);
		as_arraylist_append_int64(&list2, i+2);
		as_arraylist_append_int64(&list2, i+3);
		as_arraylist_append_int64(&list2, i+4);

		// Make a string of variable size
		for (int jj = 0; jj < i * 1024; ++jj) {
			buffer[jj] = 'X';
		}
		buffer[i * 1024] = '\0';

		// We only create the g bin for odd records.
		bool create_g_bin = i % 2 == 1;
		
		as_record r;
		as_record_init(&r, 10 + (create_g_bin ? 1 : 0));
		as_record_set_str(&r,   "a", a);
		as_record_set_int64(&r, "b", b);
		as_record_set_int64(&r, "c", c);
		as_record_set_int64(&r, "d", d);
		as_record_set_int64(&r, "e", e);
		as_record_set_str(&r,   "f", f);
		if (create_g_bin) {
			as_record_set_int64(&r, "g", g);
		}
		as_record_set_list(&r, "x", (as_list *) &list);
		as_record_set_map(&r, "y", (as_map *) &map);
		as_record_set_list(&r, "z", (as_list *) &list2);
		as_record_set_str(&r,   "bigstr", buffer);

		r.ttl = the_ttl;
		
		as_key key;
		as_key_init(&key, NAMESPACE, SET, keystr);
		
		aerospike_key_put(as, &err, NULL, &key, &r);
		as_record_destroy(&r);
		
		if (err.code != AEROSPIKE_OK) {
			error("aerospike_key_put() failed %d %s", err.code, err.message);
			return false;
		}
		
		as_record *r1 = NULL;
		
		aerospike_key_exists(as, &err, NULL, &key, &r1);
		as_key_destroy(&key);
		
		if (err.code != AEROSPIKE_OK) {
			error("aerospike_key_exists() failed %d %s", err.code, err.message);
			return false;
		}
		
		if (! r1) {
			error("key not found %s", keystr);
			return false;
		}
		
		as_record_destroy(r1);
	}
	return true;
}
/**
 * Creates 100 records and 9 indexes.
 *
 * Records are structured as:
 *      {a: String, b: Integer, c: Integer, d: Integer, e: Integer}
 *
 * The key is "a-b-c-d-e"
 *
 * The values are:
 *      a = "abc"
 *      b = 100
 *      c = <current index>
 *      d = c % 10
 *      e = b + (c + 1) * (d + 1) / 2
 */
bool query_foreach_create()
{
	as_error err;
	as_error_reset(&err);
	
	int n_recs = 100;
	
	as_status status;
	as_index_task task;
	
	// create index on "a"
	
	status = aerospike_index_create(as, &err, &task, NULL, NAMESPACE, SET, "a", "idx_test_a", AS_INDEX_STRING);
	if ( status == AEROSPIKE_OK ) {
		aerospike_index_create_wait(&err, &task, 0);
	}
	else {
		info("error(%d): %s", err.code, err.message);
	}
	
	// create index on "b"
	
	status = aerospike_index_create(as, &err, &task, NULL, NAMESPACE, SET, "b", "idx_test_b", AS_INDEX_NUMERIC);
	if ( status == AEROSPIKE_OK ) {
		aerospike_index_create_wait(&err, &task, 0);
	}
	else {
		info("error(%d): %s", err.code, err.message);
	}
	
	// create index on "c"
	
	status = aerospike_index_create(as, &err, &task, NULL, NAMESPACE, SET, "c", "idx_test_c", AS_INDEX_NUMERIC);
	if ( status == AEROSPIKE_OK ) {
		aerospike_index_create_wait(&err, &task, 0);
	}
	else {
		info("error(%d): %s", err.code, err.message);
	}
	
	// create index on "d"
	status = aerospike_index_create(as, &err, &task, NULL, NAMESPACE, SET, "d", "idx_test_d", AS_INDEX_NUMERIC);
	if ( status == AEROSPIKE_OK ) {
		aerospike_index_create_wait(&err, &task, 0);
	}
	else {
		info("error(%d): %s", err.code, err.message);
	}
	
	// create complex index on "x"
	 
	status = aerospike_index_create_complex(as, &err, &task, NULL, NAMESPACE, SET, "x", "idx_test_x", AS_INDEX_TYPE_LIST, AS_INDEX_STRING);
	if ( status == AEROSPIKE_OK ) {
		aerospike_index_create_wait(&err, &task, 0);
	}
	else {
		info("error(%d): %s", err.code, err.message);
	}
	 
	// create complex index on "y"
	 
	status = aerospike_index_create_complex(as, &err, &task, NULL, NAMESPACE, SET, "y", "idx_test_y", AS_INDEX_TYPE_MAPKEYS, AS_INDEX_STRING);
	if ( status == AEROSPIKE_OK ) {
		aerospike_index_create_wait(&err, &task, 0);
	}
	else {
		info("error(%d): %s", err.code, err.message);
	}
	 
	// create complex index on "y"
	 
	status = aerospike_index_create_complex(as, &err, &task, NULL, NAMESPACE, SET, "y", "idx_test_y1", AS_INDEX_TYPE_MAPVALUES, AS_INDEX_STRING);
	if ( status == AEROSPIKE_OK ) {
		aerospike_index_create_wait(&err, &task, 0);
	}
	else {
		info("error(%d): %s", err.code, err.message);
	}

	// create complex index on "z"
	 
	status = aerospike_index_create_complex(as, &err, &task, NULL, NAMESPACE, SET, "z", "idx_test_z", AS_INDEX_TYPE_LIST, AS_INDEX_NUMERIC);
	if ( status == AEROSPIKE_OK ) {
		aerospike_index_create_wait(&err, &task, 0);
	}
	else {
		info("error(%d): %s", err.code, err.message);
	}
	 
	// insert records
	for ( int i = 0; i < n_recs; i++ ) {
		
		char * 	a = "abc";
		int 	b = n_recs;
		int 	c = i;
		int 	d = i % 10;
		int 	e = b + (c + 1) * (d + 1) / 2;
		
		char keystr[64] = { '\0' };
		snprintf(keystr, 64, "%s-%d-%d-%d-%d", a, b, c, d, e);
		
		// Make list
		
		as_arraylist list;
		as_arraylist_init(&list, 3, 0);
		if ( (i%3) == 0) {
			as_arraylist_append_str(&list, "x");
			as_arraylist_append_str(&list, "x1");
			as_arraylist_append_str(&list, "x2");
		} else {
			as_arraylist_append_str(&list, "not_x1");
			as_arraylist_append_str(&list, "not_x2");
			as_arraylist_append_str(&list, "not_x3");

		}
		
		// Make map
		
		as_hashmap map;
		as_hashmap_init(&map, 1);
		if ( (i%7) == 0) {
			as_stringmap_set_str((as_map *) &map, "ykey", "yvalue");
		} else {
			as_stringmap_set_str((as_map *) &map, "ykey_not", "yvalue_not");

		}
		
		
		// Make list of integers
		
		as_arraylist list2;
		as_arraylist_init(&list2, 5, 0);
		as_arraylist_append_int64(&list2, i);
		as_arraylist_append_int64(&list2, i+1);
		as_arraylist_append_int64(&list2, i+2);
		as_arraylist_append_int64(&list2, i+3);
		as_arraylist_append_int64(&list2, i+4);

		
		as_record r;
		as_record_init(&r, 9);
		as_record_set_str(&r,   "a", a);
		as_record_set_int64(&r, "b", b);
		as_record_set_int64(&r, "c", c);
		as_record_set_int64(&r, "d", d);
		as_record_set_int64(&r, "e", e);
		as_record_set_list(&r, "x", (as_list *) &list);
		as_record_set_map(&r, "y", (as_map *) &map);
		as_record_set_list(&r, "z", (as_list *) &list2);
		
		as_key key;
		as_key_init(&key, NAMESPACE, SET, keystr);
		
		aerospike_key_put(as, &err, NULL, &key, &r);
		as_record_destroy(&r);
		
		if (err.code != AEROSPIKE_OK) {
			error("aerospike_key_put() failed %d %s", err.code, err.message);
			return false;
		}
		
		as_record *r1 = NULL;
		
		aerospike_key_exists(as, &err, NULL, &key, &r1);
		as_key_destroy(&key);
		
		if (err.code != AEROSPIKE_OK) {
			error("aerospike_key_exists() failed %d %s", err.code, err.message);
			return false;
		}
		
		if (! r1) {
			error("key not found %s", keystr);
			return false;
		}
		
		as_record_destroy(r1);
	}
	return true;
}
Example #14
0
/**
 *******************************************************************************************************
 * This function read a record with a given key, and return the record.
 *
 * @param self                  AerospikeClient object
 * @param py_key                The key under which to store the record.
 * @param py_policy             The dictionary of policies to be given while
 *                              reading a record.
 *
 * Returns the record on success.
 * In case of error,appropriate exceptions will be raised.
 *******************************************************************************************************
 */
PyObject * AerospikeClient_Get_Invoke(
		AerospikeClient * self,
		PyObject * py_key, PyObject * py_policy)
{
	// Python Return Value
	PyObject * py_rec = NULL;

	// Aerospike Client Arguments
	as_error err;
	as_policy_read read_policy;
	as_policy_read * read_policy_p = NULL;
	as_key key;
	as_record * rec = NULL;

	// Initialised flags
	bool key_initialised = false;
	bool record_initialised = false;

	// Initialize error
	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;
	}

	// Convert python key object to as_key
	pyobject_to_key(&err, py_key, &key);
	if ( err.code != AEROSPIKE_OK ) {
		goto CLEANUP;
	}
	// Key is successfully initialised.
	key_initialised = true;

	// Convert python policy object to as_policy_exists
	pyobject_to_policy_read(&err, py_policy, &read_policy, &read_policy_p,
			&self->as->config.policies.read);
	if ( err.code != AEROSPIKE_OK ) {
		goto CLEANUP;
	}

	// Initialize record
	as_record_init(rec, 0);
	// Record initialised successfully.
	record_initialised = true;

	// Invoke operation
	aerospike_key_get(self->as, &err, read_policy_p, &key, &rec);
	if ( err.code == AEROSPIKE_OK ) {
		record_to_pyobject(&err, rec, &key, &py_rec);
		if ( read_policy_p == NULL || 
				( read_policy_p != NULL && read_policy_p->key == AS_POLICY_KEY_DIGEST)){
			// This is a special case.
			// C-client returns NULL key, so to the user
			// response will be (<ns>, <set>, None, <digest>)
			// Using the same input key, just making primary key part to be None
			// Only in case of POLICY_KEY_DIGEST or no policy specified
			PyObject * p_key = PyTuple_GetItem( py_rec, 0 );
			Py_INCREF(Py_None);
			PyTuple_SetItem(p_key, 2, Py_None);
		}
	}
	else if( err.code == AEROSPIKE_ERR_RECORD_NOT_FOUND ) {
		as_error_reset(&err);

		PyObject * py_rec_key = NULL;
		PyObject * py_rec_meta = Py_None;
		PyObject * py_rec_bins = Py_None;

		key_to_pyobject(&err, &key, &py_rec_key);

		py_rec = PyTuple_New(3);
		PyTuple_SetItem(py_rec, 0, py_rec_key);
		PyTuple_SetItem(py_rec, 1, py_rec_meta);
		PyTuple_SetItem(py_rec, 2, py_rec_bins);

		Py_INCREF(py_rec_meta);
		Py_INCREF(py_rec_bins);
	}
	else {
		as_error_update(&err, err.code, NULL);
	}

CLEANUP:

	if (key_initialised == true){
		// Destroy key only if it is initialised.
		as_key_destroy(&key);
	}
	if (record_initialised == true){
		// Destroy record only if it is initialised.
		as_record_destroy(rec);
	}

	if ( err.code != AEROSPIKE_OK ) {
		PyObject * py_err = NULL;
		error_to_pyobject(&err, &py_err);
		PyObject *exception_type = raise_exception(&err);
		if(PyObject_HasAttrString(exception_type, "key")) {
			PyObject_SetAttrString(exception_type, "key", py_key);
		} 
		if(PyObject_HasAttrString(exception_type, "bin")) {
			PyObject_SetAttrString(exception_type, "bin", Py_None);
		}
		PyErr_SetObject(exception_type, py_err);
		Py_DECREF(py_err);
		return NULL;
	}

	return py_rec;
}
Example #15
0
/**
 *******************************************************************************************************
 * This function will put record to the Aerospike DB.
 *
 * @param self                  AerospikeClient object
 * @param py_key                The key under which to store the record.
 * @param py_bins               The data to write to the Aerospike DB.
 * @param py_meta               The meatadata for the record.
 * @param py_policy             The dictionary of policies to be given while
 *                              reading a record.
 *
 * Returns an integer status. 0(Zero) is success value.
 * In case of error,appropriate exceptions will be raised.
 *******************************************************************************************************
 */
PyObject * AerospikeClient_Put_Invoke(
		AerospikeClient * self,
		PyObject * py_key, PyObject * py_bins, PyObject * py_meta, PyObject * py_policy,
		long serializer_option)
{
	// Aerospike Client Arguments
	as_error err;
	as_policy_write write_policy;
	as_policy_write * write_policy_p = NULL;
	as_key key;
	as_record rec;

	// Initialisation flags
	bool key_initialised = false;
	bool record_initialised = false;

	// Initialize record
	as_record_init(&rec, 0);
	record_initialised = true;

	as_static_pool static_pool;
	memset(&static_pool, 0, sizeof(static_pool));

	// Initialize error
	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;
	}

	// Convert python key object to as_key
	pyobject_to_key(&err, py_key, &key);
	if (err.code != AEROSPIKE_OK) {
		goto CLEANUP;
	}
	// Key is initialised successfully.
	key_initialised = true;

	// Convert python bins and metadata objects to as_record
	pyobject_to_record(self, &err, py_bins, py_meta, &rec, serializer_option, &static_pool);
	if (err.code != AEROSPIKE_OK) {
		goto CLEANUP;
	}

	// Convert python policy object to as_policy_write
	pyobject_to_policy_write(&err, py_policy, &write_policy, &write_policy_p,
			&self->as->config.policies.write);
	if (err.code != AEROSPIKE_OK) {
		goto CLEANUP;
	}

	// Invoke operation
	Py_BEGIN_ALLOW_THREADS
	aerospike_key_put(self->as, &err, write_policy_p, &key, &rec);
	Py_END_ALLOW_THREADS
	if (err.code != AEROSPIKE_OK) {
		as_error_update(&err, err.code, NULL);
	}

CLEANUP:
	POOL_DESTROY(&static_pool);

	if (key_initialised == true) {
		// Destroy the key if it is initialised.
		as_key_destroy(&key);
	}
	if (record_initialised == true) {
		// Destroy the record if it is initialised.
		as_record_destroy(&rec);
	}

	// 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);
		if (PyObject_HasAttrString(exception_type, "key")) {
			PyObject_SetAttrString(exception_type, "key", py_key);
		} 
		if (PyObject_HasAttrString(exception_type, "bin")) {
			PyObject_SetAttrString(exception_type, "bin", py_bins);
		}
		PyErr_SetObject(exception_type, py_err);
		Py_DECREF(py_err);
		return NULL;
	}

	return PyLong_FromLong(0);
}
Example #16
0
static void key_deallocate(void *p)
{
    as_key* ptr = p;
    as_key_destroy(ptr);
}
Example #17
0
void as_ldt_clean_get_args(ErlNifEnv* env, ldt_get_args_t* args)
{
    as_ldt_destroy(&args->ldt);
    as_key_destroy(&args->key);
}
Example #18
0
static int get(lua_State *L){
	//printf("-get-\n");
	aerospike* as = lua_touserdata(L, 1);
	const char* nameSpace = luaL_checkstring(L, 2);
	const char* set = luaL_checkstring(L, 3);
	const char* keyString = luaL_checkstring(L, 4);
	//printf("key-:%s\n", keyString);
	as_record* rec = NULL;
	as_key key;
	as_error err;
	as_key_init(&key, nameSpace, set, keyString);

	// Read the test record from the database.
	aerospike_key_get(as, &err, NULL, &key, &rec);

	// Push the error code
	lua_pushnumber(L, err.code);

	// Push the error message
	lua_pushstring(L, err.message);

	// Create an new table and push it
	if ( err.code == AEROSPIKE_OK){
        
		lua_newtable(L); /* create table to hold Bins read */
		/*
		 * iterate through bin and add the bin name
		 * and value to the table
		 */
		as_record_iterator it;
		as_record_iterator_init(&it, rec);

		while (as_record_iterator_has_next(&it)) {
		    as_bin *bin        = as_record_iterator_next(&it);
		    as_val *value      = (as_val*)as_bin_get_value(bin);
            char * binName = as_bin_get_name(bin);
            
		    int bin_type = as_val_type(value); //Bin Type

		    switch (bin_type){
		    case AS_INTEGER:
                   
		    	//printf("--integer-%s-\n", binName);
			    lua_pushstring(L, binName); //Bin name
		    	lua_pushnumber(L, as_integer_get(as_integer_fromval(value)));
		    	//printf("--integer-end-\n");
		    	break;
		    case AS_DOUBLE:
                   
		    	//printf("--double-%s-\n", binName);
			    lua_pushstring(L, binName); //Bin name
		    	lua_pushnumber(L, as_double_get(as_double_fromval(value)));
		    	//printf("--double-end-\n");
		    	break;
		    case AS_STRING:
		    	//printf("--string-%s-\n", binName);
			    lua_pushstring(L, binName); //Bin name
		    	lua_pushstring(L, as_val_tostring(value));
		    	//printf("--string-end-\n");
		    	break;
		    case AS_LIST:
		    	//printf("--list-%s-\n", binName);
			    lua_pushstring(L, binName); //Bin name
		    	// Iterate through arraylist populating table
		    	as_list* p_list = as_list_fromval(value);
		    	as_arraylist_iterator it;
		    	as_arraylist_iterator_init(&it, (const as_arraylist*)p_list);
                    
                // create a Lua inner table table for the "List"
		    	lua_newtable(L);
                    
		    	int count = 0;
		    	// See if the elements match what we expect.
		    	while (as_arraylist_iterator_has_next(&it)) {
		    		const as_val* p_val = as_arraylist_iterator_next(&it);
		    		//Assume string
		    		char* p_str = as_val_tostring(p_val);
                    lua_pushnumber(L, count); // table[i]
			    	lua_pushstring(L, p_str); //Value
                    //printf("%d => %s\n", count, p_str);
			    	count++;
			    	lua_settable(L, -3);
		    	}
                //printf("--list-end-\n");
                break;
		    }
		    //printf("--settable-\n");
		    lua_settable(L, -3);
		    //printf("--settable-end-\n");
		}
	}
	as_record_destroy(rec);
	as_key_destroy(&key);
	//printf("-get-end-\n");
	return 3;
}
/**
 *******************************************************************************************************
 * This function applies a registered udf module on a particular record.
 *
 * @param self                  AerospikeClient object
 * @param py_key                The key under which the record is stored.
 * @param py_policy             The dictionary of policies
 *
 * Returns a tuple of record having key and meta sequentially.
 *******************************************************************************************************
 */
extern PyObject * AerospikeClient_Exists_Invoke(
		AerospikeClient * self,
		PyObject * py_key, PyObject * py_policy)
{
	// Python Return Value
	PyObject * py_result = NULL;

	// Aerospike Client Arguments
	as_error err;
	as_policy_read read_policy;
	as_policy_read * read_policy_p = NULL;
	as_key key;
	as_record * rec = NULL;

	// Initialisation flags
	bool key_initialised = false;

	// Initialize error
	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;
	}

	// Convert python key object to as_key
	pyobject_to_key(&err, py_key, &key);
	if ( err.code != AEROSPIKE_OK ) {
		goto CLEANUP;
	}
	// key is initialised successfully
	key_initialised = true;

	// Convert python policy object to as_policy_exists
	pyobject_to_policy_read(&err, py_policy, &read_policy, &read_policy_p,
			&self->as->config.policies.read);
	if ( err.code != AEROSPIKE_OK ) {
		goto CLEANUP;
	}

	// Invoke operation
    Py_BEGIN_ALLOW_THREADS
	aerospike_key_exists(self->as, &err, read_policy_p, &key, &rec);
    Py_END_ALLOW_THREADS

	if ( err.code == AEROSPIKE_OK ) {

		PyObject * py_result_key = NULL;
		PyObject * py_result_meta = NULL;

		key_to_pyobject(&err, &key, &py_result_key);
		metadata_to_pyobject(&err, rec, &py_result_meta);

		py_result = PyTuple_New(2);
		PyTuple_SetItem(py_result, 0, py_result_key);
		PyTuple_SetItem(py_result, 1, py_result_meta);
	}
	else {
		as_error_update(&err, err.code, NULL);
	}

CLEANUP:

	if (key_initialised == true){
		// Destroy the key if it is initialised successfully.
		as_key_destroy(&key);
	}
	as_record_destroy(rec);

	if ( err.code != AEROSPIKE_OK ) {
		PyObject * py_err = NULL;
		error_to_pyobject(&err, &py_err);
		PyObject *exception_type = raise_exception(&err);
		if(PyObject_HasAttrString(exception_type, "key")) {
			PyObject_SetAttrString(exception_type, "key", py_key);
		} 
		if(PyObject_HasAttrString(exception_type, "bin")) {
			PyObject_SetAttrString(exception_type, "bin", Py_None);
		}
		PyErr_SetObject(exception_type, py_err);
		Py_DECREF(py_err);
	}

	return py_result;
}
/**
 *******************************************************************************************************
 * This function invokes csdk's API's.
 *
 * @param self                  AerospikeClient object
 * @param err                   The as_error to be populated by the function
 *                              with the encountered error if any.
 * @param key                   The C client's as_key that identifies the record.
 * @param py_list               The list containing op, bin and value.
 * @param py_meta               The metadata for the operation.
 * @param operate_policy_p      The value for operate policy.
 *******************************************************************************************************
 */
static
PyObject *  AerospikeClient_Operate_Invoke(
	AerospikeClient * self, as_error *err,
	as_key * key, PyObject * py_list, PyObject * py_meta,
	as_policy_operate * operate_policy_p)
{
	as_val* put_val = NULL;
	char* bin = NULL;
	char* val = NULL;
	long offset = 0;
	double double_offset = 0.0;
	uint32_t ttl = 0;
	long operation = 0;
	int i = 0;
	PyObject * py_rec = NULL;
	PyObject * py_ustr = NULL;
	PyObject * py_ustr1 = NULL;
	PyObject * py_bin = NULL;
	as_record * rec = NULL;

	as_static_pool static_pool;
	memset(&static_pool, 0, sizeof(static_pool));

	as_operations ops;
	Py_ssize_t size = PyList_Size(py_list);
	as_operations_inita(&ops, size);

	if (!self || !self->as) {
		as_error_update(err, AEROSPIKE_ERR_PARAM, "Invalid aerospike object");
		goto CLEANUP;
	}

	if(py_meta) {
		AerospikeClient_CheckForMeta(py_meta, &ops, err);
	}

	if (err->code != AEROSPIKE_OK) {
		goto CLEANUP;
	}

	for ( i = 0; i < size; i++) {
		PyObject * py_val = PyList_GetItem(py_list, i);
		operation = -1;
		offset = 0;
		double_offset = 0.0;
		if ( PyDict_Check(py_val) ) {
			PyObject *key_op = NULL, *value = NULL;
			PyObject * py_value = NULL;
			Py_ssize_t pos = 0;
			while (PyDict_Next(py_val, &pos, &key_op, &value)) {
				if ( ! PyString_Check(key_op) ) {
					as_error_update(err, AEROSPIKE_ERR_CLIENT, "A operation key must be a string.");
					goto CLEANUP;
				} else {
					char * name = PyString_AsString(key_op);
					if(!strcmp(name,"op") && (PyInt_Check(value) || PyLong_Check(value))) {
						operation = PyInt_AsLong(value);
					} else if (!strcmp(name, "bin")) {
						py_bin = value;
					} else if(!strcmp(name, "val")) {
						py_value = value;
					} else {
						as_error_update(err, AEROSPIKE_ERR_PARAM, "operation can contain only op, bin and val keys");
						goto CLEANUP;
					}
				}
			}

			if (py_bin) {
				if (PyUnicode_Check(py_bin)) {
					py_ustr = PyUnicode_AsUTF8String(py_bin);
					bin = PyString_AsString(py_ustr);
				} else if (PyString_Check(py_bin)) {
					bin = PyString_AsString(py_bin);
				} else if (PyByteArray_Check(py_bin)) {
                    bin = PyByteArray_AsString(py_bin);
                } else {
                    as_error_update(err, AEROSPIKE_ERR_PARAM, "Bin name should be of type string");
					goto CLEANUP;
				}

				if (self->strict_types) {
					if (strlen(bin) > AS_BIN_NAME_MAX_LEN) {
						if (py_ustr) {
							Py_DECREF(py_ustr);
							py_ustr = NULL;
						}
						as_error_update(err, AEROSPIKE_ERR_BIN_NAME, "A bin name should not exceed 14 characters limit");
						goto CLEANUP;
					}
				}
			} else if (!py_bin && operation != AS_OPERATOR_TOUCH) {
				as_error_update(err, AEROSPIKE_ERR_PARAM, "Bin is not given");
				goto CLEANUP;
			}
			if (py_value) {
				if (self->strict_types) {
					if (check_type(self, py_value, operation, err)) {
						goto CLEANUP;
					}
				}
			} else if ((!py_value) && (operation != AS_OPERATOR_READ && operation != AS_OPERATOR_TOUCH)) {
				as_error_update(err, AEROSPIKE_ERR_PARAM, "Value should be given");
				goto CLEANUP;
			}

			switch(operation) {
				case AS_OPERATOR_APPEND:
					if (PyUnicode_Check(py_value)) {
						py_ustr1 = PyUnicode_AsUTF8String(py_value);
						val = PyString_AsString(py_ustr1);
						as_operations_add_append_str(&ops, bin, val);
					} else if (PyString_Check(py_value)) {
						val = PyString_AsString(py_value);
						as_operations_add_append_str(&ops, bin, val);
					} else if (PyByteArray_Check(py_value)) {
						as_bytes *bytes;
						GET_BYTES_POOL(bytes, &static_pool, err);
						serialize_based_on_serializer_policy(self, SERIALIZER_PYTHON, &bytes, py_value, err);
						as_operations_add_append_raw(&ops, bin, bytes->value, bytes->size);
					} else {
						if (!self->strict_types || !strcmp(py_value->ob_type->tp_name, "aerospike.null")) {
							as_operations *pointer_ops = &ops;
							as_binop *binop = &pointer_ops->binops.entries[pointer_ops->binops.size++];
							binop->op = AS_OPERATOR_APPEND;
							initialize_bin_for_strictypes(self, err, py_value, binop, bin, &static_pool);
						}
					}
					break;
				case AS_OPERATOR_PREPEND:
					if (PyUnicode_Check(py_value)) {
						py_ustr1 = PyUnicode_AsUTF8String(py_value);
						val = PyString_AsString(py_ustr1);
						as_operations_add_prepend_str(&ops, bin, val);
					} else if (PyString_Check(py_value)) {
						val = PyString_AsString(py_value);
						as_operations_add_prepend_str(&ops, bin, val);
					} else if (PyByteArray_Check(py_value)) {
						as_bytes *bytes;
						GET_BYTES_POOL(bytes, &static_pool, err);
						serialize_based_on_serializer_policy(self, SERIALIZER_PYTHON, &bytes, py_value, err);
						as_operations_add_prepend_raw(&ops, bin, bytes->value, bytes->size);
					} else {
						if (!self->strict_types || !strcmp(py_value->ob_type->tp_name, "aerospike.null")) {
							as_operations *pointer_ops = &ops;
							as_binop *binop = &pointer_ops->binops.entries[pointer_ops->binops.size++];
							binop->op = AS_OPERATOR_PREPEND;
							initialize_bin_for_strictypes(self, err, py_value, binop, bin, &static_pool);
						}
					}
					break;
				case AS_OPERATOR_INCR:
					if (PyInt_Check(py_value)) {
						offset = PyInt_AsLong(py_value);
						as_operations_add_incr(&ops, bin, offset);
					} else if ( PyLong_Check(py_value) ) {
						offset = PyLong_AsLong(py_value);
						if (offset == -1 && PyErr_Occurred()) {
							if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
								as_error_update(err, AEROSPIKE_ERR_PARAM, "integer value exceeds sys.maxsize");
								goto CLEANUP;
							}
						}
						as_operations_add_incr(&ops, bin, offset);
					} else if (PyFloat_Check(py_value)) {
						double_offset = PyFloat_AsDouble(py_value);
						as_operations_add_incr_double(&ops, bin, double_offset);
					} else {
						if (!self->strict_types || !strcmp(py_value->ob_type->tp_name, "aerospike.null")) {
							as_operations *pointer_ops = &ops;
							as_binop *binop = &pointer_ops->binops.entries[pointer_ops->binops.size++];
							binop->op = AS_OPERATOR_INCR;
							initialize_bin_for_strictypes(self, err, py_value, binop, bin, &static_pool);
						}
					}
					break;
				case AS_OPERATOR_TOUCH:
                    ops.ttl = 0;
					if (py_value && PyInt_Check(py_value)) {
                        ops.ttl = PyInt_AsLong(py_value);
                    } else if (py_value && PyLong_Check(py_value)) {
                        ttl = PyLong_AsLong(py_value);
                        if((uint32_t)-1 == ttl) {
                            as_error_update(err, AEROSPIKE_ERR_PARAM, "integer value for ttl exceeds sys.maxsize");
                            goto CLEANUP;
                        }
                        ops.ttl = ttl;
                    }
					as_operations_add_touch(&ops);
					break;
				case AS_OPERATOR_READ:
					as_operations_add_read(&ops, bin);
					break;
				case AS_OPERATOR_WRITE:
					pyobject_to_astype_write(self, err, bin, py_value, &put_val, &ops,
							&static_pool, SERIALIZER_PYTHON);
					if (err->code != AEROSPIKE_OK) {
						goto CLEANUP;
					}
					as_operations_add_write(&ops, bin, (as_bin_value *) put_val);
					break;
				default:
					if (self->strict_types) {
						as_error_update(err, AEROSPIKE_ERR_PARAM, "Invalid operation given");
						goto CLEANUP;
					}
			}
		}
	}

	// Initialize record
	as_record_init(rec, 0);

	Py_BEGIN_ALLOW_THREADS
	aerospike_key_operate(self->as, err, operate_policy_p, key, &ops, &rec);
	Py_END_ALLOW_THREADS

	if (err->code != AEROSPIKE_OK) {
		as_error_update(err, err->code, NULL);
		goto CLEANUP;
	}
	if(rec) {
		record_to_pyobject(self, err, rec, key, &py_rec);
	}

CLEANUP:
	if (py_ustr) {
		Py_DECREF(py_ustr);
	}
	if (py_ustr1) {
		Py_DECREF(py_ustr1);
	}
	if (rec) {
		as_record_destroy(rec);
	}
	if (key->valuep) {
		as_key_destroy(key);
	}
	if (put_val) {
		as_val_destroy(put_val);
	}

	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;
	}

	if (py_rec) {
		return py_rec;
	} else {
		return PyLong_FromLong(0);
	}
}