bool batch_exists_cb(const as_batch_read* results, uint32_t n, void* udata) { TSRMLS_FETCH(); as_status status = AEROSPIKE_OK; foreach_callback_udata* udata_ptr = (foreach_callback_udata*)udata; uint32_t i = 0; zval* record_metadata_p = NULL; bool null_flag = false; for (i = 0; i < n; i++) { if (results[i].result == AEROSPIKE_OK) { MAKE_STD_ZVAL(record_metadata_p); array_init(record_metadata_p); if (0 != add_assoc_long(record_metadata_p, PHP_AS_RECORD_DEFINE_FOR_GENERATION, results[i].record.gen)) { DEBUG_PHP_EXT_DEBUG("Unable to get generation of a record"); status = AEROSPIKE_ERR; goto exit; } if (0 != add_assoc_long(record_metadata_p, PHP_AS_RECORD_DEFINE_FOR_TTL, results[i].record.ttl)) { DEBUG_PHP_EXT_DEBUG("Unable to get ttl of a record"); status = AEROSPIKE_ERR; goto exit; } } else if (results[i].result == AEROSPIKE_ERR_RECORD_NOT_FOUND) { null_flag = true; } else { return false; } populate_result_for_get_exists_many((as_key *) results[i].key, udata_ptr->udata_p, record_metadata_p, udata_ptr->error_p, null_flag TSRMLS_CC); if (AEROSPIKE_OK != udata_ptr->error_p->code) { DEBUG_PHP_EXT_DEBUG("%s", udata_ptr->error_p->message); goto cleanup; } else { continue; } if (null_flag) { goto cleanup; } cleanup: if (record_metadata_p && AEROSPIKE_OK != udata_ptr->error_p->code) { zval_ptr_dtor(&record_metadata_p); } goto exit; } exit: if (udata_ptr->error_p->code != AEROSPIKE_OK) { return false; } return true; }
/* ****************************************************************************************************** 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; }
/* ****************************************************************************************************** Get the code of registered UDF module. * * @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 module_p The name of the UDF module to get from the * server. * @param module_len Length of UDF module name. * @param udf_code_p Code of the UDF to be populated by this * function. * @param language The Aerospike::UDF_TYPE_* constant. * @param options_p The optional policy. * * @return AEROSPIKE_OK if success. Otherwise AEROSPIKE_x. ****************************************************************************************************** */ extern as_status aerospike_get_registered_udf_module_code(Aerospike_object* aerospike_obj_p, as_error* error_p, char* module_p, zval* udf_code_p, long language, zval* options_p) { uint32_t init_udf_file = 0; as_udf_file udf_file; as_policy_info info_policy; TSRMLS_FETCH_FROM_CTX(aerospike_obj_p->ts); set_policy(&aerospike_obj_p->as_ref_p->as_p->config, NULL, NULL, NULL, NULL, &info_policy, NULL, NULL, NULL, options_p, error_p TSRMLS_CC); if (AEROSPIKE_OK != (error_p->code)) { DEBUG_PHP_EXT_DEBUG("Unable to set policy"); goto exit; } as_udf_file_init(&udf_file); init_udf_file = 1; if (AEROSPIKE_OK != aerospike_udf_get(aerospike_obj_p->as_ref_p->as_p, error_p, &info_policy, module_p, language, &udf_file)) { DEBUG_PHP_EXT_ERROR("%s", error_p->message); goto exit; } ZVAL_STRINGL(udf_code_p, (char*) udf_file.content.bytes, udf_file.content.size, 1); exit: if (init_udf_file) { as_udf_file_destroy(&udf_file); } return error_p->code; }
/* ******************************************************************************************************* * Wrapper function to perform an aerospike_key_remove 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 error_p The as_error to be populated by the function * with the encountered error if any. * @param options_p The user's optional policy options to be used if set, else defaults. * ******************************************************************************************************* */ extern as_status aerospike_record_operations_remove(aerospike* as_object_p, as_key* as_key_p, as_error *error_p, zval* options_p) { as_status status = AEROSPIKE_OK; as_policy_remove remove_policy; if ( (!as_key_p) || (!error_p) || (!as_object_p)) { status = AEROSPIKE_ERR; goto exit; } set_policy(NULL, NULL, NULL, &remove_policy, NULL, NULL, options_p, error_p); if (AEROSPIKE_OK != (status = (error_p->code))) { DEBUG_PHP_EXT_DEBUG("Unable to set policy"); goto exit; } if (AEROSPIKE_OK != (status = aerospike_key_remove(as_object_p, error_p, &remove_policy, as_key_p))) { goto exit; } exit: return(status); }
/* ****************************************************************************************************** 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; }
/* ******************************************************************************************************* * Wrapper function to remove bin(s) from a record. * * @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 bins_p The PHP array of bins to be removed from the record. * @param error_p The as_error to be populated by the function * with the encountered error if any. * @param options_p The user's optional policy options to be used if set, else defaults. * ******************************************************************************************************* */ extern as_status aerospike_record_operations_remove_bin(aerospike* as_object_p, as_key* as_key_p, zval* bins_p, as_error* error_p, zval* options_p) { as_status status = AEROSPIKE_OK; as_record rec; HashTable *bins_array_p = Z_ARRVAL_P(bins_p); HashPosition pointer; zval **bin_names; as_policy_write write_policy; as_record_inita(&rec, zend_hash_num_elements(bins_array_p)); if ((!as_object_p) || (!error_p) || (!as_key_p) || (!bins_array_p)) { status = AEROSPIKE_ERR; goto exit; } set_policy(NULL, &write_policy, NULL, NULL, NULL, NULL, options_p, error_p); if (AEROSPIKE_OK != (status = (error_p->code))) { DEBUG_PHP_EXT_DEBUG("Unable to set policy"); goto exit; } foreach_hashtable(bins_array_p, pointer, bin_names) { if (IS_STRING == Z_TYPE_PP(bin_names)) { if (!(as_record_set_nil(&rec, Z_STRVAL_PP(bin_names)))) { status = AEROSPIKE_ERR; goto exit; } } else { status = AEROSPIKE_ERR; goto exit; } } if (AEROSPIKE_OK != (status = aerospike_key_put(as_object_p, error_p, NULL, as_key_p, &rec))) { goto exit; } exit: as_record_destroy(&rec); return(status); }
static void populate_result_for_get_exists_many(as_key *key_p, zval *outer_container_p, zval *inner_container_p, as_error *error_p, bool null_flag TSRMLS_DC) { if (!(as_val*)(key_p->valuep)) { if (!null_flag) { if (0 != add_assoc_zval(outer_container_p, (char *) key_p->digest.value, inner_container_p)) { PHP_EXT_SET_AS_ERR(error_p, AEROSPIKE_ERR, "Unable to get key of a record"); DEBUG_PHP_EXT_DEBUG("Unable to get key of a record"); } } else { if (0 != add_assoc_null(outer_container_p, (char *) key_p->digest.value)) { PHP_EXT_SET_AS_ERR(error_p, AEROSPIKE_ERR, "Unable to get key of a record"); DEBUG_PHP_EXT_DEBUG("Unable to get key of a record"); } } } else { switch (((as_val*)(key_p->valuep))->type) { case AS_STRING: if (!null_flag) { if (0 != add_assoc_zval(outer_container_p, key_p->value.string.value, inner_container_p)) { PHP_EXT_SET_AS_ERR(error_p, AEROSPIKE_ERR, "Unable to get key of a record"); DEBUG_PHP_EXT_DEBUG("Unable to get key of a record"); } } else { if (0 != add_assoc_null(outer_container_p, key_p->value.string.value)) { PHP_EXT_SET_AS_ERR(error_p, AEROSPIKE_ERR, "Unable to get key of a record"); DEBUG_PHP_EXT_DEBUG("Unable to get key of a record"); } } break; case AS_INTEGER: if (!null_flag) { if (FAILURE == add_index_zval(outer_container_p, key_p->value.integer.value, inner_container_p)) { PHP_EXT_SET_AS_ERR(error_p, AEROSPIKE_ERR, "Unable to get key of a record"); DEBUG_PHP_EXT_DEBUG("Unable to get key of a record"); } } else { if (0 != add_index_null(outer_container_p, key_p->value.integer.value)) { PHP_EXT_SET_AS_ERR(error_p, AEROSPIKE_ERR, "Unable to get key of a record"); DEBUG_PHP_EXT_DEBUG("Unable to get key of a record"); } } break; default: break; } } }
/* ****************************************************************************************************** Remove a UDF module from the aerospike DB. * * @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 module_p The name of the UDF module to remove from the Aerospike DB. * @param module_len The module name length. * @param options_p The optional policy. * * @return AEROSPIKE_OK if success. Otherwise AEROSPIKE_x. ****************************************************************************************************** */ extern as_status aerospike_udf_deregister(Aerospike_object* aerospike_obj_p, as_error* error_p, char* module_p, zval* options_p) { as_policy_info info_policy; 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; } if (AEROSPIKE_OK != aerospike_udf_remove(aerospike_obj_p->as_ref_p->as_p, error_p, NULL, module_p)) { DEBUG_PHP_EXT_ERROR(error_p->message); goto exit; } exit: return error_p->code; }
/* ****************************************************************************************************** Get the code of registered UDF module. * * @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 module_p The name of the UDF module to get from the * server. * @param module_len Length of UDF module name. * @param udf_code_p Code of the UDF to be populated by this * function. * @param language The Aerospike::UDF_TYPE_* constant. * @param options_p The optional policy. * * @return AEROSPIKE_OK if success. Otherwise AEROSPIKE_x. ****************************************************************************************************** */ extern as_status aerospike_get_registered_udf_module_code(Aerospike_object* aerospike_obj_p, as_error* error_p, char* module_p, zval* udf_code_p, long language, zval* options_p) { uint32_t init_udf_file = 0; as_udf_file udf_file; as_policy_info info_policy; if ((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_file_init(&udf_file); init_udf_file = 1; if (AEROSPIKE_OK != aerospike_udf_get(aerospike_obj_p->as_ref_p->as_p, error_p, &info_policy, module_p, (language - AS_UDF_TYPE), &udf_file)) { DEBUG_PHP_EXT_ERROR(error_p->message); goto exit; } ZVAL_STRINGL(udf_code_p, udf_file.content.bytes, udf_file.content.size, 1); exit: if (init_udf_file) { as_udf_file_destroy(&udf_file); } return error_p->code; }
/* ******************************************************************************************************* * 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 error_p The as_error to be populated by the function * with the encountered error if any. * @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. * ******************************************************************************************************* */ extern as_status aerospike_record_operations_exists(aerospike* as_object_p, as_key* as_key_p, as_error *error_p, zval* metadata_p, zval* options_p) { as_status status = AEROSPIKE_OK; as_policy_read read_policy; as_record* record_p = NULL; if ( (!as_key_p) || (!error_p) || (!as_object_p) || (!metadata_p)) { status = AEROSPIKE_ERR; goto exit; } set_policy(&read_policy, NULL, NULL, NULL, NULL, NULL, options_p, error_p); if (AEROSPIKE_OK != (status = (error_p->code))) { DEBUG_PHP_EXT_DEBUG("Unable to set policy"); goto exit; } if (AEROSPIKE_OK != (status = aerospike_key_exists(as_object_p, error_p, &read_policy, as_key_p, &record_p))) { goto exit; } add_assoc_long(metadata_p, "generation", record_p->gen); add_assoc_long(metadata_p, "ttl", record_p->ttl); exit: if (record_p) { as_record_destroy(record_p); } return(status); }
/* ****************************************************************************************************** Registers a UDF module. * * @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 path_p The path to the module on the client side * @param language The Aerospike::UDF_TYPE_* constant. * @param options_p The optional policy. * * @return AEROSPIKE_OK if success. Otherwise AEROSPIKE_x. ****************************************************************************************************** */ extern as_status aerospike_udf_register(Aerospike_object* aerospike_obj_p, as_error* error_p, char* path_p, char* module_p, long language, zval* options_p) { FILE* file_p = NULL; uint32_t size = 0; uint32_t content_size; uint8_t* bytes_p = NULL; uint8_t* buff_p = NULL; uint32_t read; as_bytes udf_content; as_bytes* udf_content_p = NULL; as_policy_info info_policy; TSRMLS_FETCH_FROM_CTX(aerospike_obj_p->ts); set_policy(&aerospike_obj_p->as_ref_p->as_p->config, NULL, NULL, NULL, NULL, &info_policy, NULL, NULL, NULL, options_p, error_p TSRMLS_CC); if (AEROSPIKE_OK != (error_p->code)) { DEBUG_PHP_EXT_DEBUG("Unable to set policy"); goto exit; } file_p = fopen(path_p, "r"); if (!file_p) { PHP_EXT_SET_AS_ERR(error_p, AEROSPIKE_ERR_UDF_NOT_FOUND, "Cannot open script file"); DEBUG_PHP_EXT_DEBUG("Cannot open script file"); goto exit; } fseek(file_p, 0L, SEEK_END); content_size = ftell(file_p); fseek(file_p, 0L, SEEK_SET); /* * Using emalloc here to maintain consistency of PHP extension. * malloc can also be used for C-SDK. * if emalloc is used, pass parameter 4 of function as_bytes_init_wrap as * "false" and handle the freeing up of the same here. */ if (NULL == (bytes_p = (uint8_t *) emalloc(content_size + 1))) { PHP_EXT_SET_AS_ERR(error_p, AEROSPIKE_ERR, "Memory allocation failed for contents of UDF"); DEBUG_PHP_EXT_DEBUG("Memory allocation failed for contents of UDF"); goto exit; } buff_p = bytes_p; read = (int) fread(buff_p, 1, LUA_FILE_BUFFER_FRAME, file_p); while (read) { size += read; buff_p += read; read = (int) fread(buff_p, 1, LUA_FILE_BUFFER_FRAME, file_p); } as_bytes_init_wrap(&udf_content, bytes_p, size, false); udf_content_p = &udf_content; /* * Register the UDF file in the database cluster. */ if (AEROSPIKE_OK != aerospike_udf_put(aerospike_obj_p->as_ref_p->as_p, error_p, &info_policy, module_p, language, udf_content_p)) { DEBUG_PHP_EXT_DEBUG("%s", error_p->message); goto exit; } else if (AEROSPIKE_OK != aerospike_udf_put_wait(aerospike_obj_p->as_ref_p->as_p, error_p, &info_policy, module_p, 0)) { DEBUG_PHP_EXT_DEBUG("%s", error_p->message); goto exit; } exit: if (file_p) { fclose(file_p); } if (bytes_p) { efree(bytes_p); } if (udf_content_p) { as_bytes_destroy(udf_content_p); } return error_p->code; }
/* ******************************************************************************************************* * Wrapper function to perform an aerospike_key_oeprate 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 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. * @param bin_name_p The bin name to perform operation upon. * @param str The string to be appended in case of operation: append. * @param offset The offset to be incremented by in case of operation: increment. * @param initial_value The initial value to be set if record is absent * in case of operation: increment. * @param time_to_live The ttl for the record in case of operation: touch. * @param operation The operation type. * ******************************************************************************************************* */ extern as_status aerospike_record_operations_ops(aerospike* as_object_p, as_key* as_key_p, zval* options_p, as_error* error_p, int8_t* bin_name_p, int8_t* str, u_int64_t offset, u_int64_t initial_value, u_int64_t time_to_live, u_int64_t operation) { as_status status = AEROSPIKE_OK; as_policy_operate operate_policy; uint32_t serializer_policy; as_record* get_rec = NULL; as_operations ops; as_val* value_p = NULL; as_integer initial_int_val; int16_t initialize_int = 0; const char *select[] = {bin_name_p, NULL}; as_operations_inita(&ops, 1); as_policy_operate_init(&operate_policy); if ((!as_object_p) || (!error_p) || (!as_key_p)) { status = AEROSPIKE_ERR; goto exit; } set_policy(NULL, NULL, &operate_policy, NULL, NULL, &serializer_policy, options_p, error_p); if (AEROSPIKE_OK != (status = (error_p->code))) { DEBUG_PHP_EXT_DEBUG("Unable to set policy"); goto exit; } switch(operation) { case AS_OPERATOR_APPEND: as_operations_add_append_str(&ops, bin_name_p, str); break; case AS_OPERATOR_PREPEND: as_operations_add_prepend_str(&ops, bin_name_p, str); break; case AS_OPERATOR_INCR: if (AEROSPIKE_OK != (status = aerospike_key_select(as_object_p, error_p, NULL, as_key_p, select, &get_rec))) { goto exit; } else { if (NULL != (value_p = (as_val *) as_record_get (get_rec, bin_name_p))) { if (AS_NIL == value_p->type) { as_integer_init(&initial_int_val, initial_value); initialize_int = 1; if (!as_operations_add_write(&ops, bin_name_p, (as_bin_value*) &initial_int_val)) { status = AEROSPIKE_ERR; goto exit; } } else { as_operations_add_incr(&ops, bin_name_p, offset); } } else { status = AEROSPIKE_ERR; goto exit; } } break; case AS_OPERATOR_TOUCH: ops.ttl = time_to_live; as_operations_add_touch(&ops); break; default: status = AEROSPIKE_ERR; goto exit; break; } if (AEROSPIKE_OK != (status = aerospike_key_operate(as_object_p, error_p, &operate_policy, as_key_p, &ops, &get_rec))) { goto exit; } exit: as_operations_destroy(&ops); if (get_rec) { as_record_destroy(get_rec); } if (initialize_int) { as_integer_destroy(&initial_int_val); } return status; }