/*
 ******************************************************************************************************
 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;
}
Exemple #2
0
// ----------------------------------------------------------------------------------
//
// 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;
}