static as_status as_scan_parse_record_async(as_event_command* cmd, uint8_t** pp, as_msg* msg, as_error* err) { as_record rec; as_record_inita(&rec, msg->n_ops); rec.gen = msg->generation; rec.ttl = cf_server_void_time_to_ttl(msg->record_ttl); *pp = as_command_parse_key(*pp, msg->n_fields, &rec.key); as_status status = as_command_parse_bins(pp, err, &rec, msg->n_ops, cmd->flags2 & AS_ASYNC_FLAGS2_DESERIALIZE); if (status != AEROSPIKE_OK) { as_record_destroy(&rec); return status; } as_event_executor* executor = cmd->udata; // udata is overloaded to contain executor. bool rv = ((as_async_scan_executor*)executor)->listener(0, &rec, executor->udata, executor->event_loop); as_record_destroy(&rec); if (! rv) { executor->notify = false; return as_error_set_message(err, AEROSPIKE_ERR_CLIENT_ABORT, ""); } return AEROSPIKE_OK; }
// ---------------------------------------------------------------------------------- // // check if key exist in cluster // // def exists?(key, options = {}) // // params: // key - AerospikeC::Key object // options - hash of options: // policy: AerospikeC::Policy for read // // ------ // RETURN: // 1. true if exist // 2. false otherwise // static VALUE key_exists(int argc, VALUE * argv, VALUE self) { rb_aero_TIMED(tm); as_error err; as_status status; aerospike * as = rb_aero_CLIENT; as_record * rec = NULL; VALUE key; VALUE options; rb_scan_args(argc, argv, "11", &key, &options); if ( NIL_P(options) ) options = rb_hash_new(); as_key * k = rb_aero_KEY; as_policy_read * policy = get_policy(options); if ( ( status = aerospike_key_exists(as, &err, policy, k, &rec) ) != AEROSPIKE_OK ) { as_record_destroy(rec); if ( status == AEROSPIKE_ERR_RECORD_NOT_FOUND ) { rb_aero_logger(AS_LOG_LEVEL_DEBUG, &tm, 2, rb_str_new2("[Client][exists?] success - false"), rb_aero_KEY_INFO); return Qfalse; } raise_as_error(err); } as_record_destroy(rec); rb_aero_logger(AS_LOG_LEVEL_DEBUG, &tm, 2, rb_str_new2("[Client][exists?] success - true"), rb_aero_KEY_INFO); return Qtrue; }
static as_status as_scan_parse_record(uint8_t** pp, as_msg* msg, as_scan_task* task, as_error* err) { as_record rec; as_record_inita(&rec, msg->n_ops); rec.gen = msg->generation; rec.ttl = cf_server_void_time_to_ttl(msg->record_ttl); *pp = as_command_parse_key(*pp, msg->n_fields, &rec.key); as_status status = as_command_parse_bins(pp, err, &rec, msg->n_ops, task->scan->deserialize_list_map); if (status != AEROSPIKE_OK) { as_record_destroy(&rec); return status; } bool rv = true; if (task->callback) { rv = task->callback((as_val*)&rec, task->udata); } as_record_destroy(&rec); return rv ? AEROSPIKE_OK : AEROSPIKE_ERR_CLIENT_ABORT; }
// ---------------------------------------------------------------------------------- // // adding record to the cluster // // def put(key, bins, options = {}) // // params: // key - AerospikeC::Key object // bins - either hash {"bin name" => "value"} or AerospikeC::Record object // options - hash of options: // ttl: time to live record (default: 0) // policy: AerospikeC::Policy for write // // ------ // RETURN: // 1. true if completed succesfuly // 2. nil when AEROSPIKE_ERR_RECORD_NOT_FOUND // static VALUE put(int argc, VALUE * argv, VALUE self) { rb_aero_TIMED(tm); as_status status; as_error err; aerospike * as = rb_aero_CLIENT; VALUE key; VALUE hash; VALUE options; rb_scan_args(argc, argv, "21", &key, &hash, &options); if ( NIL_P(options) ) options = rb_hash_new(); VALUE option_tmp; long len = rb_ary_len_long(hash); as_record rec; as_record_init(&rec, len); hash2record(hash, &rec); as_key * k = rb_aero_KEY; as_policy_write * policy = get_policy(options); if ( !NIL_P(options) ) { VALUE rb_ttl = rb_hash_aref(options, ttl_sym); if ( TYPE(rb_ttl) == T_FIXNUM ) { rec.ttl = FIX2INT( rb_ttl ); } } if ( ( status = aerospike_key_put(as, &err, policy, k, &rec) ) != AEROSPIKE_OK) { as_record_destroy(&rec); if ( status == AEROSPIKE_ERR_RECORD_NOT_FOUND ) { rb_aero_logger(AS_LOG_LEVEL_WARN, &tm, 2, rb_str_new2("[Client][put] AEROSPIKE_ERR_RECORD_NOT_FOUND"), rb_aero_KEY_INFO); return Qnil; } raise_as_error(err); } as_record_destroy(&rec); rb_aero_logger(AS_LOG_LEVEL_DEBUG, &tm, 2, rb_str_new2("[Client][put] success"), rb_aero_KEY_INFO); return Qtrue; }
//------------------------------------------------ // Read the whole test record from the database. // bool example_read_test_record(aerospike* p_as) { as_error err; as_record* p_rec = NULL; // Read the test record from the database. if (aerospike_key_get(p_as, &err, NULL, &g_key, &p_rec) != AEROSPIKE_OK) { LOG("aerospike_key_get() returned %d - %s", err.code, err.message); return false; } // If we didn't get an as_record object back, something's wrong. if (! p_rec) { LOG("aerospike_key_get() retrieved null as_record object"); return false; } // Log the result. LOG("record was successfully read from database:"); example_dump_record(p_rec); // Destroy the as_record object. as_record_destroy(p_rec); return true; }
/** * The is the proxy callback function. This will be passed to the old simple-scan * mechanism. When this gets called, it will create an as_val structure out of the * record and will call the callback that user supplied (folded into the udata structure) */ static int simplescan_cb(char *ns, cf_digest *keyd, char *set, cl_object *key, int result, uint32_t generation, uint32_t record_void_time, cl_bin *bins, uint16_t n_bins, void *udata) { scan_bridge * bridge = (scan_bridge *) udata; // Fill the bin data as_record _rec, * rec = &_rec; as_record_inita(rec, n_bins); clbins_to_asrecord(bins, (uint32_t)n_bins, rec); // Fill the metadata askey_from_clkey(&rec->key, ns, set, key); memcpy(rec->key.digest.value, keyd, sizeof(cf_digest)); rec->key.digest.init = true; rec->gen = generation; rec->ttl = record_void_time; // Call the callback that user wanted to callback bool rv = bridge->callback((as_val *) rec, bridge->udata); // The responsibility to free the bins is on the called callback function // In scan case, only LIST & MAP will have an active free citrusleaf_bins_free(bins, (int)n_bins); // release the record as_record_destroy(rec); return rv ? 0 : 1; }
// Called when writes encounter a "doomed" record, to delete the doomed record // and create a new one in place without giving up the record lock. // FIXME - won't be able to "rescue" with future sindex method - will go away. void as_record_rescue(as_index_ref *r_ref, as_namespace *ns) { record_delete_adjust_sindex(r_ref->r, ns); as_record_destroy(r_ref->r, ns); as_index_clear_record_info(r_ref->r); cf_atomic64_incr(&ns->n_objects); }
// ---------------------------------------------------------------------------------- // // def touch(key, options = {}) // // params: // key - AeropsikeC::Key object // options - hash of options: // ttl: time to live record (default: 0) // policy: AerospikeC::Policy for operate // // ------ // RETURN: // 1. hash representing record header // 2. nil when AEROSPIKE_ERR_RECORD_NOT_FOUND // // @TODO options policy // static VALUE touch(int argc, VALUE * argv, VALUE self) { rb_aero_TIMED(tm); as_error err; as_status status; aerospike * as = rb_aero_CLIENT; VALUE key; VALUE options; rb_scan_args(argc, argv, "11", &key, &options); // default values for optional arguments if ( NIL_P(options) ) { options = rb_hash_new(); rb_hash_aset(options, ttl_sym, rb_zero); } else { if ( TYPE(rb_hash_aref(options, ttl_sym)) != T_FIXNUM ) { // check ttl option rb_raise(rb_aero_OptionError, "[AerospikeC::Client][put] ttl must be an integer"); } } as_key * k = rb_aero_KEY; as_record * rec = NULL; as_operations ops; as_operations_inita(&ops, 1); as_operations_add_touch(&ops); ops.ttl = FIX2INT( rb_hash_aref(options, ttl_sym) ); as_policy_operate * policy = get_policy(options); if ( ( status = aerospike_key_operate(as, &err, policy, k, &ops, &rec) ) != AEROSPIKE_OK ) { as_operations_destroy(&ops); if ( status == AEROSPIKE_ERR_RECORD_NOT_FOUND ) { rb_aero_logger(AS_LOG_LEVEL_WARN, &tm, 2, rb_str_new2("[Client][touch] AEROSPIKE_ERR_RECORD_NOT_FOUND"), rb_aero_KEY_INFO); return Qnil; } raise_as_error(err); } VALUE header = rb_hash_new(); rb_hash_aset(header, rb_str_new2("gen"), INT2FIX(rec->gen)); rb_hash_aset(header, rb_str_new2("expire_in"), INT2FIX(rec->ttl)); as_record_destroy(rec); as_operations_destroy(&ops); rb_aero_logger(AS_LOG_LEVEL_DEBUG, &tm, 2, rb_str_new2("[Client][touch] success"), rb_aero_KEY_INFO); return header; }
// Done with record - unlock. If record was removed from tree and is not // reserved (by reduce), destroy record and free arena element. void as_record_done(as_index_ref *r_ref, as_namespace *ns) { as_record *r = r_ref->r; if (! as_index_is_valid_record(r) && r->rc == 0) { as_record_destroy(r, ns); cf_arenax_free(ns->arena, r_ref->r_h, r_ref->puddle); } cf_mutex_unlock(r_ref->olock); }
// ---------------------------------------------------------------------------------- // // def get_header(key, options = {}) // // params: // key - AerospikeC::Key object // options - hash of options: // policy: AerospikeC::Policy for read // // ------ // RETURN: // 1. hash representing record header // 2. nil when AEROSPIKE_ERR_RECORD_NOT_FOUND // static VALUE get_header(int argc, VALUE * argv, VALUE self) { rb_aero_TIMED(tm); as_error err; as_status status; aerospike * as = rb_aero_CLIENT; as_record * rec = NULL; VALUE key; VALUE options; rb_scan_args(argc, argv, "11", &key, &options); if ( NIL_P(options) ) options = rb_hash_new(); as_key * k = rb_aero_KEY; as_policy_read * policy = get_policy(options); if ( ( status = aerospike_key_exists(as, &err, policy, k, &rec) ) != AEROSPIKE_OK ) { as_record_destroy(rec); if ( status == AEROSPIKE_ERR_RECORD_NOT_FOUND ) { rb_aero_logger(AS_LOG_LEVEL_WARN, &tm, 2, rb_str_new2("[Client][get_header] AEROSPIKE_ERR_RECORD_NOT_FOUND"), rb_aero_KEY_INFO); return Qnil; } raise_as_error(err); } VALUE header = rb_hash_new(); rb_hash_aset(header, rb_str_new2("gen"), INT2FIX(rec->gen)); rb_hash_aset(header, rb_funcall(rb_aero_AerospikeC, rb_intern("ttl_name"), 0), INT2FIX(rec->ttl)); as_record_destroy(rec); rb_aero_logger(AS_LOG_LEVEL_DEBUG, &tm, 2, rb_str_new2("[Client][get_header] success"), rb_aero_KEY_INFO); return header; }
/* ******************************************************************************************************* * 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); }
bool as_event_command_parse_result(as_event_command* cmd) { as_msg* msg = (as_msg*)cmd->buf; as_msg_swap_header_from_be(msg); uint8_t* p = cmd->buf + sizeof(as_msg); as_status status = msg->result_code; switch (status) { case AEROSPIKE_OK: { as_record rec; if (msg->n_ops < 1000) { as_record_inita(&rec, msg->n_ops); } else { as_record_init(&rec, msg->n_ops); } rec.gen = msg->generation; rec.ttl = cf_server_void_time_to_ttl(msg->record_ttl); p = as_command_ignore_fields(p, msg->n_fields); as_command_parse_bins(&rec, p, msg->n_ops, cmd->deserialize); as_event_response_complete(cmd); ((as_async_record_command*)cmd)->listener(0, &rec, cmd->udata, cmd->event_loop); as_event_command_release(cmd); as_record_destroy(&rec); break; } case AEROSPIKE_ERR_UDF: { as_error err; as_command_parse_udf_failure(p, &err, msg, status); as_event_response_error(cmd, &err); break; } default: { as_error err; as_error_set_message(&err, status, as_error_string(status)); as_event_response_error(cmd, &err); break; } } return true; }
// ---------------------------------------------------------------------------------- // // perform given operations on record in one call // // def operate(key, operations, options = {}) // // params: // key - AeropsikeC::Key object // operations - AeropsikeC::Operation object // options: // policy: AerospikeC::Policy for operate // // ------ // RETURN: // 1. hash representing record // 2. nil when AEROSPIKE_ERR_RECORD_NOT_FOUND // // static VALUE operate(int argc, VALUE * argv, VALUE self) { rb_aero_TIMED(tm); as_error err; as_status status; aerospike * as = rb_aero_CLIENT; VALUE key; VALUE operations; VALUE options; rb_scan_args(argc, argv, "21", &key, &operations, &options); if ( NIL_P(options) ) { options = rb_hash_new(); } as_key * k = rb_aero_KEY; VALUE is_aerospike_c_operation = rb_funcall(operations, rb_intern("is_a?"), 1, rb_aero_OPERATION); if ( is_aerospike_c_operation != Qtrue ) { rb_raise(rb_aero_OptionError, "[AerospikeC::Client][operate] use AerospikeC::Operation class to perform operations"); } as_operations * ops = rb_operations2as_operations(operations); as_record * rec = NULL; as_policy_operate * policy = get_policy(options); if ( ( status = aerospike_key_operate(as, &err, policy, k, ops, &rec) ) != AEROSPIKE_OK ) { as_operations_destroy(ops); if ( status == AEROSPIKE_ERR_RECORD_NOT_FOUND ) { rb_aero_logger(AS_LOG_LEVEL_WARN, &tm, 2, rb_str_new2("[Client][operate] AEROSPIKE_ERR_RECORD_NOT_FOUND"), rb_aero_KEY_INFO); return Qnil; } raise_as_error(err); } VALUE record = record2hash(rec); as_record_destroy(rec); as_operations_destroy(ops); rb_aero_logger(AS_LOG_LEVEL_DEBUG, &tm, 2, rb_str_new2("[Client][operate] success"), rb_aero_KEY_INFO); return record; }
static bool asc_raw_read(aerospike* p_as, as_key* p_key, uint8_t *buf, uint32_t size) { as_status status; as_error err; // Read the (whole) test record from the database. as_record *rec = NULL; status = aerospike_key_get(p_as, &err, NULL, p_key, &rec); if (status != AEROSPIKE_OK) { ERROR("aerospike_key_get() returned %d - %s", err.code, err.message); return false; } // Read the record as_bytes *bytes = as_record_get_bytes(rec, "data"); memcpy(buf, bytes->value, MIN(bytes->size, size)); as_record_destroy(rec); return true; }
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; }
bool asc_size(aerospike *p_as, char *ns, char *file, uint32_t *size) { as_status status; as_error err; // Prepare the key as_key key; as_key_init_str(&key, ns, SET, file); // Read metadata as_record *rec = NULL; status = aerospike_key_get(p_as, &err, NULL, &key, &rec); if (status != AEROSPIKE_OK) { ERROR("aerospike_key_get() returned %d - %s", err.code, err.message); return false; } *size = as_record_get_int64(rec, "size", 0); as_record_destroy(rec); return true; }
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); } }
/* ******************************************************************************************************* * 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); }
//------------------------------------------------ // Read multiple-record examples' test records // from the database. // bool example_read_test_records(aerospike* p_as) { // Multiple-record examples insert g_n_keys records, using integer keys from // 0 to (g_n_keys - 1). for (uint32_t i = 0; i < g_n_keys; i++) { as_error err; // No need to destroy a stack as_key object, if we only use // as_key_init_int64(). as_key key; as_key_init_int64(&key, g_namespace, g_set, (int64_t)i); as_record* p_rec = NULL; // Read a test record from the database. if (aerospike_key_get(p_as, &err, NULL, &key, &p_rec) != AEROSPIKE_OK) { LOG("aerospike_key_get() returned %d - %s", err.code, err.message); return false; } // If we didn't get an as_record object back, something's wrong. if (! p_rec) { LOG("aerospike_key_get() retrieved null as_record object"); return false; } // Log the result. LOG("read record with key %u from database:", i); example_dump_record(p_rec); // Destroy the as_record object. as_record_destroy(p_rec); } return true; }
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 policy; as_policy_read * policy_p = NULL; as_key key; as_record * rec = NULL; // Initialize error as_error_init(&err); // Convert python key object to as_key pyobject_to_key(&err, py_key, &key); if ( err.code != AEROSPIKE_OK ) { goto CLEANUP; } // Convert python policy object to as_policy_exists pyobject_to_policy_read(&err, py_policy, &policy, &policy_p); if ( err.code != AEROSPIKE_OK ) { goto CLEANUP; } // Invoke operation aerospike_key_exists(self->as, &err, policy_p, &key, &rec); 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 if ( err.code == AEROSPIKE_ERR_RECORD_NOT_FOUND ) { as_error_reset(&err); PyObject * py_result_key = NULL; PyObject * py_result_meta = Py_None; key_to_pyobject(&err, &key, &py_result_key); py_result = PyTuple_New(2); PyTuple_SetItem(py_result, 0, py_result_key); PyTuple_SetItem(py_result, 1, py_result_meta); Py_INCREF(py_result_meta); } CLEANUP: as_record_destroy(rec); if ( err.code != AEROSPIKE_OK ) { PyObject * py_err = NULL; error_to_pyobject(&err, &py_err); PyErr_SetObject(PyExc_Exception, 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; }
static as_status batch_read( aerospike * as, as_error * err, const as_policy_batch * policy, const as_batch * batch, aerospike_batch_read_callback callback, void * udata, bool get_bin_data ) { as_error_reset(err); // Lazily initialize batch machinery: cl_cluster_batch_init(as->cluster); uint32_t n = batch->keys.size; as_batch_read* results = (as_batch_read*)alloca(sizeof(as_batch_read) * n); if (! results) { return as_error_update(err, AEROSPIKE_ERR_CLIENT, "failed results array allocation"); } cf_digest* digests = (cf_digest*)alloca(sizeof(cf_digest) * n); if (! digests) { return as_error_update(err, AEROSPIKE_ERR_CLIENT, "failed digests array allocation"); } // Because we're wrapping the old functionality, we only support a batch // with all keys in the same namespace. char* ns = batch->keys.entries[0].ns; for (uint32_t i = 0; i < n; i++) { if (strcmp(ns, batch->keys.entries[i].ns) != 0) { // Don't need to destroy results' records since they won't have any // associated allocations yet. return as_error_update(err, AEROSPIKE_ERR_PARAM, "batch keys must all be in the same namespace"); } as_batch_read * p_r = &results[i]; p_r->result = -1; // TODO - make an 'undefined' error as_record_init(&p_r->record, 0); p_r->key = (const as_key*)as_batch_keyat(batch, i); memcpy(&digests[i], as_key_digest((as_key*)p_r->key)->value, AS_DIGEST_VALUE_SIZE); } batch_bridge bridge; bridge.as = as; bridge.results = results; bridge.n = n; cl_rv rc = citrusleaf_batch_read(as->cluster, ns, digests, n, NULL, 0, get_bin_data, cl_batch_cb, &bridge); callback(results, n, udata); for (uint32_t i = 0; i < n; i++) { as_record_destroy(&results[i].record); } return as_error_fromrc(err, rc); }
/** * 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; }
/** ******************************************************************************************************* * 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; }
/** * aerospike::create(record) * Function: udf_aerospike_rec_create * * Parameters: * as - as_aerospike * rec - as_rec * * Return Values: * 1 if record is being read or on a create, it already exists * o/w return value of udf_aerospike__execute_updates * * Description: * Create a new record in local storage. * The record will only be created if it does not exist. * This assumes the record has a digest that is valid for local storage. * * Synchronization : object lock acquired by the transaction thread executing UDF. * Partition reservation takes place just before the transaction starts executing * ( look for as_partition_reserve_udf in thr_tsvc.c ) * * Callers: * lua interfacing function, mod_lua_aerospike_rec_create * The return value of udf_aerospike_rec_create is pushed on to the lua stack * * Notes: * The 'read' and 'exists' flag of udf_record are set to true. */ static int udf_aerospike_rec_create(const as_aerospike * as, const as_rec * rec) { int ret = udf_aerospike_param_check(as, rec, __FILE__, __LINE__); if (ret) { return ret; } udf_record * urecord = (udf_record *) as_rec_source(rec); // make sure record isn't already successfully read if (urecord->flag & UDF_RECORD_FLAG_OPEN) { cf_detail(AS_UDF, "udf_aerospike_rec_create: Record Already Exists"); return 1; } as_transaction *tr = urecord->tr; as_index_ref *r_ref = urecord->r_ref; as_storage_rd *rd = urecord->rd; as_index_tree *tree = tr->rsv.tree; bool is_subrec = false; if (urecord->flag & UDF_RECORD_FLAG_IS_SUBRECORD) { tree = tr->rsv.sub_tree; is_subrec = true; } // make sure we got the record as a create bool is_create = false; int rv = as_record_get_create(tree, &tr->keyd, r_ref, tr->rsv.ns, is_subrec); cf_detail_digest(AS_UDF, &tr->keyd, "Creating %sRecord", (urecord->flag & UDF_RECORD_FLAG_IS_SUBRECORD) ? "Sub" : ""); // rv 0 means record exists, 1 means create, < 0 means fail // TODO: Verify correct result codes. if (rv == 1) { is_create = true; } else if (rv == 0) { // If it's an expired record, pretend it's a fresh create. if (as_record_is_expired(r_ref->r)) { as_record_destroy(r_ref->r, tr->rsv.ns); as_record_initialize(r_ref, tr->rsv.ns); cf_atomic_int_incr(&tr->rsv.ns->n_objects); is_create = true; } else { cf_warning(AS_UDF, "udf_aerospike_rec_create: Record Already Exists 2"); as_record_done(r_ref, tr->rsv.ns); // DO NOT change it has special meaning for caller return 1; } } else if (rv < 0) { cf_warning(AS_UDF, "udf_aerospike_rec_create: Record Open Failed with rv=%d", rv); return rv; } // Associates the set name with the storage rec and index if (tr->msgp) { // Set the set name to index and close record if the setting the set name // is not successful int rv_set = as_transaction_has_set(tr) ? as_record_set_set_from_msg(r_ref->r, tr->rsv.ns, &tr->msgp->msg) : 0; if (rv_set != 0) { cf_warning(AS_UDF, "udf_aerospike_rec_create: Failed to set setname"); if (is_create) { as_index_delete(tree, &tr->keyd); } as_record_done(r_ref, tr->rsv.ns); return 4; } } urecord->flag |= UDF_RECORD_FLAG_OPEN; cf_detail(AS_UDF, "Open %p %x %"PRIx64"", urecord, urecord->flag, *(uint64_t *)&tr->keyd); as_index *r = r_ref->r; // open up storage as_storage_record_create(urecord->tr->rsv.ns, urecord->r_ref->r, urecord->rd, &urecord->tr->keyd); cf_detail(AS_UDF, "as_storage_record_create: udf_aerospike_rec_create: r %p rd %p", urecord->r_ref->r, urecord->rd); // If the message has a key, apply it to the record. if (! get_msg_key(tr, rd)) { cf_warning(AS_UDF, "udf_aerospike_rec_create: Can't store key"); if (is_create) { as_index_delete(tree, &tr->keyd); } as_record_done(r_ref, tr->rsv.ns); urecord->flag &= ~UDF_RECORD_FLAG_OPEN; return 4; } // if multibin storage, we will use urecord->stack_bins, so set the size appropriately if ( ! rd->ns->storage_data_in_memory && ! rd->ns->single_bin ) { rd->n_bins = sizeof(urecord->stack_bins) / sizeof(as_bin); } // side effect: will set the unused bins to properly unused rd->bins = as_bin_get_all(r, rd, urecord->stack_bins); urecord->flag |= UDF_RECORD_FLAG_STORAGE_OPEN; cf_detail(AS_UDF, "Storage Open %p %x %"PRIx64"", urecord, urecord->flag, *(uint64_t *)&tr->keyd); cf_detail(AS_UDF, "udf_aerospike_rec_create: Record created %d", urecord->flag); int rc = udf_aerospike__execute_updates(urecord); if (rc) { // Creating the udf record failed, destroy the as_record cf_warning(AS_UDF, "udf_aerospike_rec_create: failure executing record updates (%d)", rc); if (!as_bin_inuse_has(urecord->rd)) { udf_aerospike_rec_remove(as, rec); } } return rc; }
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; }
/** ****************************************************************************************************** * Removes a bin from a record. * * @param self AerospikeClient object * @prama py_key The key for the record. * @pram py_binList The name of the bins to be removed from the record. * @param py_policy The optional policies. * @param err The C client's as_error to be set to the encountered error. * * Returns an integer status. 0(Zero) is success value. * In case of error,appropriate exceptions will be raised. ******************************************************************************************************* */ static PyObject * AerospikeClient_RemoveBin_Invoke( AerospikeClient * self, PyObject * py_key,PyObject* py_binList ,PyObject * py_policy, PyObject * py_meta, as_error *err) { // Aerospike Client Arguments as_policy_write write_policy; as_policy_write * write_policy_p = NULL; as_key key; as_record rec; char* binName = NULL; int count = 0; PyObject * py_ustr = NULL; // Get the bin list size; Py_ssize_t size = PyList_Size(py_binList); // Initialize record as_record_inita(&rec, size); // Convert python key object to as_key pyobject_to_key(err, py_key, &key); 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 ) { as_error_update(err, AEROSPIKE_ERR_CLIENT, "Incorrect policy"); goto CLEANUP; } // Invoke operation for ( count = 0; count < size; count++ ) { PyObject * py_val = PyList_GetItem(py_binList, count); if( PyUnicode_Check(py_val) ){ py_ustr = PyUnicode_AsUTF8String(py_val); binName = PyStr_AsString(py_ustr); } else if( PyStr_Check(py_val) ) { binName = PyStr_AsString(py_val); } else { as_error_update(err, AEROSPIKE_ERR_CLIENT, "Invalid bin name, bin name should be a string or unicode string") goto CLEANUP; } if (!as_record_set_nil(&rec, binName)){ goto CLEANUP; } if (py_ustr) { Py_DECREF(py_ustr); py_ustr = NULL; } } if ( py_meta && PyDict_Check(py_meta) ) { PyObject * py_gen = PyDict_GetItemString(py_meta, "gen"); PyObject * py_ttl = PyDict_GetItemString(py_meta, "ttl"); if( py_ttl != NULL ){ if ( PyInt_Check(py_ttl) ) { rec.ttl = (uint32_t) PyInt_AsLong(py_ttl); } else if ( PyLong_Check(py_ttl) ) { rec.ttl = (uint32_t) PyLong_AsLongLong(py_ttl); if((uint32_t)-1 == rec.ttl) { as_error_update(err, AEROSPIKE_ERR_PARAM, "integer value for ttl exceeds sys.maxsize"); goto CLEANUP; } } else { as_error_update(err, AEROSPIKE_ERR_PARAM, "Ttl should be an int or long"); goto CLEANUP; } } if( py_gen != NULL ){ if ( PyInt_Check(py_gen) ) { rec.gen = (uint16_t) PyInt_AsLong(py_gen); } else if ( PyLong_Check(py_gen) ) { rec.gen = (uint16_t) PyLong_AsLongLong(py_gen); if((uint16_t)-1 == rec.gen) { 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"); goto CLEANUP; } } } 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); goto CLEANUP; } CLEANUP: 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 PyLong_FromLong(0); }
SourceRecord::~SourceRecord() { if (record_) { as_record_destroy(record_); } }
/** ******************************************************************************************************* * 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 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); }