/* ****************************************************************************************************** Applies a UDF to a record at the Aerospike DB. * * @param aerospike_obj_p The C client's aerospike object. * @param as_key_p The C client's as_key that identifies the * record on which UDF will be applied. * @param error_p The C client's as_error to be set to the encountered error. * @param module_p The name of the UDF module registered * against the Aerospike DB. * @param function_p The name of the function to be applied to * the record. * @param args_pp An array of arguments for the UDF. * @param return_value_p It will contain result value of calling the * UDF. * @param options_p The optional policy. * * @return AEROSPIKE_OK if success. Otherwise AEROSPIKE_x. ****************************************************************************************************** */ extern as_status aerospike_udf_apply(Aerospike_object* aerospike_obj_p, as_key* as_key_p, as_error* error_p, char* module_p, char* function_p, zval** args_pp, zval* return_value_p, zval* options_p) { as_arraylist args_list; as_arraylist* args_list_p = NULL; as_static_pool udf_pool = {0}; as_val* udf_result_p = NULL; foreach_callback_udata udf_result_callback_udata; uint32_t serializer_policy = -1; as_policy_apply apply_policy; TSRMLS_FETCH_FROM_CTX(aerospike_obj_p->ts); set_policy_udf_apply(&aerospike_obj_p->as_ref_p->as_p->config, &apply_policy, &serializer_policy, options_p, error_p TSRMLS_CC); if (AEROSPIKE_OK != (error_p->code)) { DEBUG_PHP_EXT_DEBUG("Unable to set policy"); goto exit; } if ((*args_pp)) { as_arraylist_inita(&args_list, zend_hash_num_elements(Z_ARRVAL_PP(args_pp))); args_list_p = &args_list; AS_LIST_PUT(NULL, args_pp, args_list_p, &udf_pool, serializer_policy, error_p TSRMLS_CC); } if (AEROSPIKE_OK != (aerospike_key_apply(aerospike_obj_p->as_ref_p->as_p, error_p, &apply_policy, as_key_p, module_p, function_p, (as_list *) args_list_p, &udf_result_p))) { DEBUG_PHP_EXT_DEBUG("%s", error_p->message); goto exit; } if (return_value_p) { udf_result_callback_udata.udata_p = return_value_p; udf_result_callback_udata.error_p = error_p; AS_DEFAULT_GET(NULL, udf_result_p, &udf_result_callback_udata); } exit: if (udf_result_p) { as_val_destroy(udf_result_p); } if (args_list_p) { as_arraylist_destroy(args_list_p); } /* clean up the as_* objects that were initialised */ aerospike_helper_free_static_pool(&udf_pool); return error_p->code; }
as_status aerospike_lset_exists( aerospike * as, as_error * err, const as_policy_apply * policy, const as_key * key, const as_ldt * ldt, const as_val * val, as_boolean *exists) { if ( !err ) { return AEROSPIKE_ERR_PARAM; } as_error_reset(err); if (!as || !key || !ldt || !exists) { return as_error_set(err, AEROSPIKE_ERR_PARAM, "invalid parameter. " "as/key/ldt/n cannot be null"); } if (ldt->type != AS_LDT_LSET) { return as_error_set(err, AEROSPIKE_ERR_PARAM, "invalid parameter. " "not lset type"); } /* stack allocate the arg list */ as_string ldt_bin; as_string_init(&ldt_bin, (char *)ldt->name, false); as_arraylist arglist; as_arraylist_inita(&arglist, 2); as_arraylist_append_string(&arglist, &ldt_bin); as_val_reserve( val ); // bump the ref count as_arraylist_append(&arglist, (as_val *)val); as_val* p_return_val = NULL; aerospike_key_apply( as, err, policy, key, DEFAULT_LSET_PACKAGE, LDT_SET_OP_EXISTS, (as_list *)&arglist, &p_return_val); as_arraylist_destroy(&arglist); if (ldt_parse_error(err) != AEROSPIKE_OK) { return err->code; } if (!p_return_val) { return as_error_set(err, AEROSPIKE_ERR_LDT_INTERNAL, "no value returned from server"); } int64_t ival = as_integer_getorelse(as_integer_fromval(p_return_val), -1); as_val_destroy(p_return_val); if (ival == -1) { return as_error_set(err, AEROSPIKE_ERR_LDT_INTERNAL, "value returned from server not parse-able"); } as_boolean_init(exists, ival==1 ? true: false); return err->code; } // aerospike_lset_exists()
// ======================================================================= // Pass in a value into the UDF -- and then get it back. Simple. // This is used to measure the performance of the end to end // call infrastructure. // Pass in LDT Bin and Value. // Return Value. // ======================================================================= as_status aerospike_lstack_same( aerospike * as, as_error * err, const as_policy_apply * policy, const as_key * key, const as_ldt * ldt, uint32_t in_val, uint32_t * out_valp) { if ( !err ) { return AEROSPIKE_ERR_PARAM; } as_error_reset(err); if (!as || !key || !ldt || !out_valp) { return as_error_set(err, AEROSPIKE_ERR_PARAM, "invalid parameter. " "as/key/ldt/out_valp cannot be null"); } if (ldt->type != AS_LDT_LSTACK) { return as_error_set(err, AEROSPIKE_ERR_PARAM, "invalid parameter. " "not LSTACK type"); } // stack allocate the arg list. // Pass in the LDT Bin and the IN VALUE. as_string ldt_bin; as_string_init(&ldt_bin, (char *)ldt->name, false); as_arraylist arglist; as_arraylist_inita(&arglist, 2); as_arraylist_append_string(&arglist, &ldt_bin); as_arraylist_append_int64(&arglist, in_val); as_val* p_return_val = NULL; aerospike_key_apply( as, err, policy, key, DEFAULT_LSTACK_PACKAGE, LDT_STACK_OP_SAME, (as_list *)&arglist, &p_return_val); as_arraylist_destroy(&arglist); if (ldt_parse_error(err) != AEROSPIKE_OK) { return err->code; } int64_t ival = as_integer_getorelse(as_integer_fromval(p_return_val), -1); as_val_destroy(p_return_val); if (ival == -1) { return as_error_set(err, AEROSPIKE_ERR_LDT_INTERNAL, "value returned from server not parse-able"); } if (ival !=0 ) { return as_error_set(err, AEROSPIKE_ERR_LDT_INTERNAL, "same() Function Failed"); } *out_valp = (uint32_t)ival; return err->code; } // end as_status aerospike_lstack_same()
// ======================================================================= static as_status aerospike_lstack_push_internal( aerospike * as, as_error * err, const as_policy_apply * policy, const as_key * key, const as_ldt * ldt, const as_val * val, const char *operation) { if ( !err ) { return AEROSPIKE_ERR_PARAM; } as_error_reset(err); if (!as || !key || !ldt || !val) { return as_error_set(err, AEROSPIKE_ERR_PARAM, "invalid parameter. " "as/key/ldt/n cannot be null"); } if (ldt->type != AS_LDT_LSTACK) { return as_error_set(err, AEROSPIKE_ERR_PARAM, "invalid parameter. " "not stack type"); } /* stack allocate the arg list */ as_string ldt_bin; as_string_init(&ldt_bin, (char *)ldt->name, false); as_arraylist arglist; as_arraylist_inita(&arglist, ldt->module[0] == 0 ? 2 : 3); as_arraylist_append_string(&arglist, &ldt_bin); as_val_reserve( val ); as_arraylist_append(&arglist, (as_val *) val); if (ldt->module[0] != 0) { as_string ldt_module; as_string_init(&ldt_module, (char *)ldt->module, false); as_arraylist_append_string(&arglist, &ldt_module); } as_val* p_return_val = NULL; aerospike_key_apply( as, err, policy, key, DEFAULT_LSTACK_PACKAGE, operation, (as_list *)&arglist, &p_return_val); as_arraylist_destroy(&arglist); if (ldt_parse_error(err) != AEROSPIKE_OK) { return err->code; } // return value is the input if (p_return_val) { as_val_destroy(p_return_val); } return err->code; } // end aerospike_lstack_push_internal()
// ======================================================================= as_status aerospike_lstack_set_capacity( aerospike * as, as_error * err, const as_policy_apply * policy, const as_key * key, const as_ldt * ldt, uint32_t elements_capacity ) { if ( !err ) { return AEROSPIKE_ERR_PARAM; } as_error_reset(err); if (!as || !key || !ldt || !elements_capacity) { return as_error_set(err, AEROSPIKE_ERR_PARAM, "invalid parameter. " "as/key/ldt/capacity cannot be null"); } if (ldt->type != AS_LDT_LSTACK) { return as_error_set(err, AEROSPIKE_ERR_PARAM, "invalid parameter. " "not stack type"); } /* stack allocate the arg list */ as_string ldt_bin; as_string_init(&ldt_bin, (char *)ldt->name, false); as_arraylist arglist; as_arraylist_inita(&arglist, 2); as_arraylist_append_string(&arglist, &ldt_bin); as_arraylist_append_int64(&arglist, elements_capacity); as_val* p_return_val = NULL; aerospike_key_apply( as, err, policy, key, DEFAULT_LSTACK_PACKAGE, LDT_STACK_OP_CAPACITY_SET, (as_list *)&arglist, &p_return_val); as_arraylist_destroy(&arglist); if (ldt_parse_error(err) != AEROSPIKE_OK) { return err->code; } int64_t ival = as_integer_getorelse(as_integer_fromval(p_return_val), -1); as_val_destroy(p_return_val); if (ival == -1) { return as_error_set(err, AEROSPIKE_ERR_LDT_INTERNAL, "value returned from server not parse-able"); } if (ival !=0 ) { return as_error_set(err, AEROSPIKE_ERR_LDT_INTERNAL, "capacity setting failed"); } return err->code; }
// ======================================================================= // Internal function to handle all of the functions that get an int back // from a call. // size() // one() // ======================================================================= as_status aerospike_lstack_ask_internal( aerospike * as, as_error * err, const as_policy_apply * policy, const as_key * key, const as_ldt * ldt, uint32_t *n, const char *operation ) { if ( !err ) { return AEROSPIKE_ERR_PARAM; } as_error_reset(err); if (!as || !key || !ldt || !n) { return as_error_set(err, AEROSPIKE_ERR_PARAM, "invalid parameter. " "as/key/ldt/n cannot be null"); } if (ldt->type != AS_LDT_LSTACK) { return as_error_set(err, AEROSPIKE_ERR_PARAM, "invalid parameter. " "not stack type"); } /* stack allocate the arg list */ as_string ldt_bin; as_string_init(&ldt_bin, (char *)ldt->name, false); // All we need to pass in is the LDT Bin Name as_arraylist arglist; as_arraylist_inita(&arglist, 1); as_arraylist_append_string(&arglist, &ldt_bin); as_val* p_return_val = NULL; aerospike_key_apply( as, err, policy, key, DEFAULT_LSTACK_PACKAGE, operation, (as_list *)&arglist, &p_return_val); as_arraylist_destroy(&arglist); if (ldt_parse_error(err) != AEROSPIKE_OK) { return err->code; } if (!p_return_val) { return as_error_set(err, AEROSPIKE_ERR_LDT_INTERNAL, "no value returned from server"); } int64_t ival = as_integer_getorelse(as_integer_fromval(p_return_val), -1); as_val_destroy(p_return_val); if (ival == -1) { return as_error_set(err, AEROSPIKE_ERR_LDT_INTERNAL, "value returned from server not parse-able"); } *n = (uint32_t)ival; return err->code; } // end as_status aerospike_lstack_ask_internal()
as_status aerospike_llist_find( aerospike * as, as_error * err, const as_policy_apply * policy, const as_key * key, const as_ldt * ldt, const as_val * search_val, as_list ** elements ) { if ( !err ) { return AEROSPIKE_ERR_PARAM; } as_error_reset(err); if (!as || !key || !ldt || !search_val || !elements) { return as_error_set(err, AEROSPIKE_ERR_PARAM, "invalid parameter. " "as/key/ldt/search_val/elements cannot be null"); } if (ldt->type != AS_LDT_LLIST) { return as_error_set(err, AEROSPIKE_ERR_PARAM, "invalid parameter. " "not llist type"); } int list_argc = 2; /* stack allocate the arg list */ as_string ldt_bin; as_string_init(&ldt_bin, (char *)ldt->name, false); as_arraylist arglist; as_arraylist_inita(&arglist, list_argc); as_arraylist_append_string(&arglist, &ldt_bin); as_val_reserve( search_val ); // bump the ref count so the arraylist_destroy will not reset the search_val as_arraylist_append(&arglist, (as_val *) search_val); as_val* p_return_val = NULL; aerospike_key_apply( as, err, policy, key, DEFAULT_LLIST_PACKAGE, LDT_LIST_OP_FIND, (as_list *)&arglist, &p_return_val); as_arraylist_destroy(&arglist); if (ldt_parse_error(err) != AEROSPIKE_OK) { return err->code; } if (!p_return_val) { return as_error_set(err, AEROSPIKE_ERR_LDT_INTERNAL, "no value returned from server"); } *elements = (as_list *)p_return_val; return err->code; } // aerospike_llist_find()
// ---------------------------------------------------------------------------------- // // execute udf on record // // def execute_udf(key, module_name, func_name, udf_args = [], options = {}) // // params: // key - AeropsikeC::Key object // module_name - string, registered module name // func_name - string, function name in module to execute // udf_args - arguments passed to udf // options: // policy - AerospikeC::ApplyPolicy // // ------ // RETURN: // 1. data returned from udf // static VALUE execute_udf(int argc, VALUE * argv, VALUE self) { rb_aero_TIMED(tm); as_error err; as_status status; aerospike * as = rb_aero_CLIENT; VALUE key; VALUE module_name; VALUE func_name; VALUE udf_args; VALUE options; rb_scan_args(argc, argv, "32", &key, &module_name, &func_name, &udf_args, &options); // default values for optional arguments if ( NIL_P(options) ) options = rb_hash_new(); if ( NIL_P(udf_args) ) udf_args = rb_ary_new(); as_key * k = rb_aero_KEY; as_arraylist * args = array2as_list(udf_args); as_policy_apply * policy = get_policy(options); as_val * res = NULL; char * c_module_name = StringValueCStr(module_name); char * c_func_name = StringValueCStr(func_name); if ( ( status = aerospike_key_apply(as, &err, policy, k, c_module_name, c_func_name, (as_list *)args, &res) ) != AEROSPIKE_OK ) { as_arraylist_destroy(args); if ( status == AEROSPIKE_ERR_RECORD_NOT_FOUND ) { rb_aero_logger(AS_LOG_LEVEL_WARN, &tm, 3, rb_str_new2("[Client][execute_udf] AEROSPIKE_ERR_RECORD_NOT_FOUND"), rb_aero_KEY_INFO, rb_aero_MOD_INFO); return Qnil; } raise_as_error(err); } VALUE result = as_val2rb_val(res); as_val_destroy(&res); as_arraylist_destroy(args); VALUE key_info = rb_aero_KEY_INFO; rb_aero_logger(AS_LOG_LEVEL_DEBUG, &tm, 3, rb_str_new2("[Client][execute_udf] success"), rb_aero_KEY_INFO, rb_aero_MOD_INFO); return result; }
as_status aerospike_llist_remove( aerospike * as, as_error * err, const as_policy_apply * policy, const as_key * key, const as_ldt * ldt, const as_val *val ) { if ( !err ) { return AEROSPIKE_ERR_PARAM; } as_error_reset(err); if (!as || !key || !ldt) { return as_error_set(err, AEROSPIKE_ERR_PARAM, "invalid parameter. " "as/key/ldt/capacity cannot be null"); } if (ldt->type != AS_LDT_LLIST) { return as_error_set(err, AEROSPIKE_ERR_PARAM, "invalid parameter. " "not llist type"); } /* stack allocate the arg list */ as_string ldt_bin; as_string_init(&ldt_bin, (char *)ldt->name, false); as_arraylist arglist; as_arraylist_inita(&arglist, 2); as_arraylist_append_string(&arglist, &ldt_bin); as_val_reserve( val ); as_arraylist_append(&arglist, (as_val *) val); as_val* p_return_val = NULL; aerospike_key_apply( as, err, policy, key, DEFAULT_LLIST_PACKAGE, LDT_LIST_OP_REMOVE, (as_list *)&arglist, &p_return_val); as_arraylist_destroy(&arglist); if (ldt_parse_error(err) != AEROSPIKE_OK) { return err->code; } if (p_return_val != NULL) { as_val_destroy(p_return_val); } return err->code; }
as_status aerospike_lset_get( aerospike * as, as_error * err, const as_policy_apply * policy, const as_key * key, const as_ldt * ldt, const as_val * val, as_val **pp_return_val) { if ( !err ) { return AEROSPIKE_ERR_PARAM; } as_error_reset(err); if (!as || !key || !ldt || !pp_return_val) { return as_error_set(err, AEROSPIKE_ERR_PARAM, "invalid parameter. " "as/key/ldt/return cannot be null"); } if (ldt->type != AS_LDT_LSET) { return as_error_set(err, AEROSPIKE_ERR_PARAM, "invalid parameter. " "not lset type"); } /* stack allocate the arg list */ as_string ldt_bin; as_string_init(&ldt_bin, (char *)ldt->name, false); as_arraylist arglist; as_arraylist_inita(&arglist, 2); as_arraylist_append_string(&arglist, &ldt_bin); as_val_reserve( val ); // bump the ref count as_arraylist_append(&arglist, (as_val *)val); aerospike_key_apply( as, err, policy, key, DEFAULT_LSET_PACKAGE, LDT_SET_OP_GET, (as_list *)&arglist, pp_return_val); as_arraylist_destroy(&arglist); if (ldt_parse_error(err) != AEROSPIKE_OK) { return err->code; } if (! *pp_return_val) { return as_error_set(err, AEROSPIKE_ERR_LDT_INTERNAL, "no value returned from server"); } return err->code; } // aerospike_lset_get()
as_status aerospike_llist_filter( aerospike * as, as_error * err, const as_policy_apply * policy, const as_key * key, const as_ldt * ldt, const as_udf_function_name filter, const as_list *filter_args, as_list ** elements ) { if ( !err ) { return AEROSPIKE_ERR_PARAM; } as_error_reset(err); if (filter_args && !filter) { return as_error_set(err, AEROSPIKE_ERR_PARAM, "invalid parameter. " "filter arguments without filter name specification"); } if (!as || !key || !ldt || !elements) { return as_error_set(err, AEROSPIKE_ERR_PARAM, "invalid parameter. " "as/key/ldt/peek_count/elements cannot be null"); } if (ldt->type != AS_LDT_LLIST) { return as_error_set(err, AEROSPIKE_ERR_PARAM, "invalid parameter. " "not llist type"); } int list_argc = filter ? 3 : 1; /* stack allocate the arg list */ as_string ldt_bin; as_string_init(&ldt_bin, (char *)ldt->name, false); as_arraylist arglist; as_arraylist_inita(&arglist, list_argc); as_arraylist_append_string(&arglist, &ldt_bin); if (filter){ as_string filter_name; as_string_init(&filter_name, (char *)filter, false); as_arraylist_append_string(&arglist, &filter_name ); as_val_reserve( filter_args ); // bump the ref count as_arraylist_append(&arglist, (as_val *) filter_args ); } as_val* p_return_val = NULL; aerospike_key_apply( as, err, policy, key, DEFAULT_LLIST_PACKAGE, filter ? LDT_LIST_OP_FILTER : LDT_LIST_OP_SCAN, (as_list *)&arglist, &p_return_val); as_arraylist_destroy(&arglist); if (ldt_parse_error(err) != AEROSPIKE_OK) { return err->code; } if (!p_return_val) { return as_error_set(err, AEROSPIKE_ERR_LDT_INTERNAL, "no value returned from server"); } *elements = (as_list *)p_return_val; return err->code; } // aerospike_llist_filter()
/** ******************************************************************************************************* * 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; }
as_hashmap map; as_hashmap_init(&map, 1); as_stringmap_set_int64((as_map *) &map, "x", (int64_t)7); as_stringmap_set_int64((as_map *) &map, "y", (int64_t)8); as_stringmap_set_int64((as_map *) &map, "z", (int64_t)9); as_val_reserve((as_map *) &map); as_arraylist_append(&arglist, (as_val *)((as_map *) &map)); as_val * res = NULL; as_key key; as_key_init(&key, NAMESPACE, SET, "foo"); as_status rc = aerospike_key_apply(as, &err, NULL, &key, UDF_FILE, "map_arg", (as_list*) &arglist, &res); as_key_destroy(&key); as_hashmap_destroy(&map); assert_int_eq( rc, AEROSPIKE_OK ); assert_not_null( res ); as_val_destroy(&arglist); as_val_destroy(res); } TEST( key_apply_put , "put: (test,test,foo) = {a: 123, b: 'abc', c: 456, d: 'def', e: [1,2,3], f: {x: 7, y: 8, z: 9}}" ) { as_error err; as_error_reset(&err);
int main(int argc, char* argv[]) { // Parse command line arguments. if (! example_get_opts(argc, argv, EXAMPLE_BASIC_OPTS)) { exit(-1); } // Connect to the aerospike database cluster. aerospike as; example_connect_to_aerospike(&as); // Start clean. example_remove_test_record(&as); // Register the UDF in the database cluster. if (! example_register_udf(&as, UDF_FILE_PATH)) { example_cleanup(&as); exit(-1); } // Write a record to the database. if (! write_record(&as)) { cleanup(&as); exit(-1); } as_error err; // Apply a simple UDF, with no arguments and no return value. if (aerospike_key_apply(&as, &err, NULL, &g_key, UDF_MODULE, "test_bin_1_add_1000", NULL, NULL) != AEROSPIKE_OK) { LOG("aerospike_key_apply() returned %d - %s", err.code, err.message); cleanup(&as); exit(-1); } LOG("test_bin_1_add_1000() was successfully applied"); if (! example_read_test_record(&as)) { example_cleanup(&as); exit(-1); } // Create an argument list for a (different) UDF. By using // as_arraylist_inita() we avoid some but not all internal heap usage, so we // must call as_arraylist_destroy(). as_arraylist args; as_arraylist_inita(&args, 3); as_arraylist_append_str(&args, "test-bin-2"); as_arraylist_append_int64(&args, 4); as_arraylist_append_int64(&args, 400); // Expect an integer return value. as_val* p_return_val = NULL; // Apply a UDF with arguments and a return value. if (aerospike_key_apply(&as, &err, NULL, &g_key, UDF_MODULE, "bin_transform", (as_list*)&args, &p_return_val) != AEROSPIKE_OK) { LOG("aerospike_key_apply() returned %d - %s", err.code, err.message); as_arraylist_destroy(&args); cleanup(&as); exit(-1); } as_arraylist_destroy(&args); if (! p_return_val) { LOG("aerospike_key_apply() retrieved null as_val object"); cleanup(&as); exit(-1); } // Extract an integer from the as_val returned. int64_t i_val = as_integer_getorelse(as_integer_fromval(p_return_val), -1); // Caller's responsibility to destroy as_val returned. as_val_destroy(p_return_val); if (i_val == -1) { LOG("aerospike_key_apply() retrieved non-as_integer object"); cleanup(&as); exit(-1); } LOG("bin_transform() was successfully applied - returned %" PRId64, i_val); if (! example_read_test_record(&as)) { example_cleanup(&as); exit(-1); } // Cleanup and disconnect from the database cluster. cleanup(&as); LOG("udf example successfully completed"); return 0; }