/* ****************************************************************************************************** Lists the UDF modules registered with the server. * * @param aerospike_obj_p The C client's aerospike object. * @param error_p The C client's as_error to be set to the encountered error. * @param array_of_modules_p An array of registered UDF modules * against the Aerospike DB to be populated by * this function. * @param language Optionally filters a subset of modules * matching the given type. * @options_p The optional parameters to the * Aerospike::listRegistered(). * * @return AEROSPIKE_OK if success. Otherwise AEROSPIKE_x. ****************************************************************************************************** */ extern as_status aerospike_list_registered_udf_modules(Aerospike_object* aerospike_obj_p, as_error* error_p, zval* array_of_modules_p, long language, zval* options_p) { as_udf_files udf_files; uint32_t init_udf_files = 0; uint32_t i=0; as_policy_info info_policy; if ((language != -1) && ((language & AS_UDF_TYPE) != AS_UDF_TYPE)) { PHP_EXT_SET_AS_ERR(error_p, AEROSPIKE_ERR_PARAM, "Invalid Value for language"); DEBUG_PHP_EXT_ERROR("Invalid value for language"); goto exit; } set_policy(NULL, NULL, NULL, NULL, &info_policy, NULL, options_p, error_p); if (AEROSPIKE_OK != (error_p->code)) { DEBUG_PHP_EXT_DEBUG("Unable to set policy"); goto exit; } as_udf_files_init(&udf_files, 0); init_udf_files = 1; if (AEROSPIKE_OK != aerospike_udf_list(aerospike_obj_p->as_ref_p->as_p, error_p, &info_policy, &udf_files)) { DEBUG_PHP_EXT_ERROR(error_p->message); goto exit; } for (i = 0; i < udf_files.size; i++) { if ((language != -1) && ((udf_files.entries[i].type) != (language - AS_UDF_TYPE))) { continue; } zval* module_p = NULL; MAKE_STD_ZVAL(module_p); array_init(module_p); add_assoc_stringl(module_p, UDF_MODULE_NAME, udf_files.entries[i].name, strlen(udf_files.entries[i].name), 1); add_assoc_long(module_p, UDF_MODULE_TYPE, (udf_files.entries[i].type + AS_UDF_TYPE)); add_next_index_zval(array_of_modules_p, module_p); } exit: if (init_udf_files) { as_udf_files_destroy(&udf_files); } return error_p->code; }
// ---------------------------------------------------------------------------------- // // list all udfs // // def list_udf(options = {}) // // params: // options - ? // // ------ // RETURN: // 1. array of hashes representing each udf // // @TODO options policy // static VALUE list_udf(int argc, VALUE * argv, VALUE self) { as_error err; aerospike * as = rb_aero_CLIENT; VALUE options; rb_scan_args(argc, argv, "01", &options); // default values for optional arguments if ( NIL_P(options) ) options = rb_hash_new(); as_udf_files files; as_udf_files_init(&files, 0); if ( aerospike_udf_list(as, &err, NULL, &files) != AEROSPIKE_OK ) raise_as_error(err); VALUE udfs = rb_ary_new(); for( int i = 0; i < files.size; i++ ) { as_udf_file * file = &files.entries[i]; VALUE udf_file = rb_hash_new(); VALUE udf_type; if ( file->type == 0 ) udf_type = lua_sym; rb_hash_aset(udf_file, name_sym, rb_str_new2(file->name)); rb_hash_aset(udf_file, udf_type_sym, udf_type); rb_hash_aset(udf_file, hash_sym, INT2FIX(file->hash)); rb_ary_push(udfs, udf_file); } as_udf_files_destroy(&files); return udfs; }
/** ******************************************************************************************************* * Lists the UDF modules registered with the server * * @param self AerospikeClient object * @param args The args is a tuple object containing an argument * list passed from Python to a C function * @param kwds Dictionary of keywords * * Returns list of modules that are registered with Aerospike DB. ******************************************************************************************************* */ PyObject * AerospikeClient_UDF_List(AerospikeClient * self, PyObject *args, PyObject * kwds) { // Initialize error as_error err; as_error_init(&err); int init_udf_files = 0; // Python Function Arguments PyObject * py_policy = NULL; as_policy_info info_policy; as_policy_info *info_policy_p = NULL; // Python Function Keyword Arguments static char * kwlist[] = {"policy", NULL}; // Python Function Argument Parsing if ( PyArg_ParseTupleAndKeywords(args, kwds, "|O:udf_list", kwlist, &py_policy) == false ) { 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 object to policy_info pyobject_to_policy_info( &err, py_policy, &info_policy, &info_policy_p, &self->as->config.policies.info); if ( err.code != AEROSPIKE_OK ) { goto CLEANUP; } as_udf_files files; as_udf_files_init(&files, 0); init_udf_files = 1; // Invoke operation Py_BEGIN_ALLOW_THREADS aerospike_udf_list(self->as, &err, info_policy_p, &files); Py_END_ALLOW_THREADS if ( err.code != AEROSPIKE_OK ) { as_error_update(&err, err.code, NULL); goto CLEANUP; } // Convert as_udf_files struct into python object PyObject * py_files; as_udf_files_to_pyobject(&err, &files, &py_files); if ( err.code != AEROSPIKE_OK ) { as_error_update(&err, err.code, NULL); goto CLEANUP; } CLEANUP: if (init_udf_files) { as_udf_files_destroy(&files); } 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, "module")) { PyObject_SetAttrString(exception_type, "module", Py_None); } if(PyObject_HasAttrString(exception_type, "func")) { PyObject_SetAttrString(exception_type, "func", Py_None); } PyErr_SetObject(exception_type, py_err); Py_DECREF(py_err); return NULL; } return py_files; }
/** * @return AEROSPIKE_OK if successful. Otherwise an error occurred. */ as_status aerospike_udf_list( aerospike * as, as_error * err, const as_policy_info * policy, as_udf_files * files) { as_error_reset(err); if (! policy) { policy = &as->config.policies.info; } char* response = 0; as_status status = aerospike_info_any(as, err, policy, "udf-list", &response); if (status) { return status; } // response := udf-list\tfilename=<name>,hash=<hash>,type=<type>;[filename=<name>...] char* p = strchr(response, '\t'); if (!p) { as_error_update(err, AEROSPIKE_ERR_PARAM, "Invalid udf-list response: %s", response); free(response); return AEROSPIKE_ERR_PARAM; } p++; uint32_t capacity = (files->capacity <= 0) ? 500 : files->capacity; as_vector ptrs; as_vector_inita(&ptrs, sizeof(as_udf_file_ptr), capacity); as_udf_file_ptr ptr = {0,0,0}; char* token = p; while (*p) { switch (*p) { case '=': *p++ = 0; as_udf_parse_file(token, p, &ptr); break; case ',': *p++ = 0; token = p; break; case ';': *p++ = 0; token = p; as_vector_append(&ptrs, &ptr); ptr.name = 0; ptr.hash = 0; ptr.type = 0; break; default: p++; break; } } if (files->capacity == 0 && files->entries == NULL) { as_udf_files_init(files, ptrs.size); } uint32_t limit = ptrs.size < files->capacity ? ptrs.size : files->capacity; files->size = limit; for (uint32_t i = 0; i < limit; i++) { as_udf_file_ptr* ptr = as_vector_get(&ptrs, i); as_udf_file* file = &files->entries[i]; if (ptr->name) { as_strncpy(file->name, ptr->name, AS_UDF_FILE_NAME_SIZE); } else { file->name[0] = 0; } if (ptr->hash) { // The hash is not null terminated, so normal strncpy is appropriate here. // strncpy will also pad zeroes if hash size is incorrect. strncpy((char*)file->hash, ptr->hash, AS_UDF_FILE_HASH_SIZE); } else { file->hash[0] = 0; } file->type = AS_UDF_TYPE_LUA; file->content._free = false; file->content.size = 0; file->content.capacity = 0; file->content.bytes = NULL; } as_vector_destroy(&ptrs); free(response); return AEROSPIKE_OK; }