bool query_cb(const as_val* p_val, void* udata) { if (! p_val) { LOG("query callback returned null - query is complete"); return true; } // Because of the UDF used, we expect an as_integer to be returned. as_integer* p_integer = as_integer_fromval(p_val); if (! p_integer) { LOG("query callback returned non-as_integer object"); return true; } LOG("query callback returned %" PRId64, as_integer_get(p_integer)); return true; }
/* * Internal function: udf_aerospike_setbin * * Parameters: * r -- udf_record to be manipulated * bname -- name of the bin to be deleted * val -- value to be updated with * * Return value: * 0 on success * -1 on failure * * Description: * The function sets the bin with the name * passed in as parameter to the value, passed as the third parameter. * Before updating the bin, it is checked if the value can fit in the 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: * udf_aerospike__apply_update_atomic * In this function, if it fails at the time of update, the record is set * to rollback all the updates till this point. The case where it fails in * rollback is not handled. * * Side Notes: * i. write_to_device will be set to true on a successful bin update. * If all the updates from udf_aerospike__apply_update_atomic (including this) are * successful, the record will be written to disk and reopened so that the rest of * sets of updates can be applied. * * ii. If put in sindex fails, we do not handle it. * * TODO make sure anything goes into setbin only if the bin value is * changed */ static const int udf_aerospike_setbin(udf_record * urecord, const char * bname, const as_val * val, bool is_hidden) { if (bname == NULL || bname[0] == 0 ) { cf_warning(AS_UDF, "no bin name supplied"); return -1; } uint8_t type = as_val_type(val); if (is_hidden && ((type != AS_MAP) && (type != AS_LIST))) { cf_warning(AS_UDF, "Hidden %d Type Not allowed", type); return -3; } size_t blen = strlen(bname); as_storage_rd * rd = urecord->rd; as_transaction *tr = urecord->tr; as_index_ref * index = urecord->r_ref; as_bin * b = as_bin_get(rd, (byte *)bname, blen); if ( !b && (blen > (AS_ID_BIN_SZ - 1 ) || !as_bin_name_within_quota(rd->ns, (byte *)bname, blen)) ) { // Can't write bin cf_warning(AS_UDF, "bin name %s too big. Bin not added", bname); return -1; } if ( !b ) { // See if there's a free one, the hope is you will always find the bin because // you have already allocated bin space before calling this function. b = as_bin_create(index->r, rd, (byte *)bname, blen, 0); if (!b) { cf_warning(AS_UDF, "ERROR: udf_aerospike_setbin: as_bin_create: bin not found, something went really wrong!"); return -1; } } SINDEX_BINS_SETUP(oldbin, 1); SINDEX_BINS_SETUP(newbin, 1); bool needs_sindex_delete = false; bool needs_sindex_put = false; bool needs_sindex_update = false; bool has_sindex = as_sindex_ns_has_sindex(rd->ns); if (has_sindex && (as_sindex_sbin_from_bin(rd->ns, as_index_get_set_name(rd->r, rd->ns), b, oldbin) == AS_SINDEX_OK)) { needs_sindex_delete = true; } // we know we are doing an update now, make sure there is particle data, // set to be 1 wblock size now @TODO! uint32_t pbytes = 0; int ret = 0; if (!rd->ns->storage_data_in_memory && !urecord->particle_data) { urecord->particle_data = cf_malloc(rd->ns->storage_write_block_size); urecord->cur_particle_data = urecord->particle_data; urecord->end_particle_data = urecord->particle_data + rd->ns->storage_write_block_size; } cf_detail(AS_UDF, "udf_setbin: bin %s type %d ", bname, type ); switch(type) { case AS_STRING: { as_string * v = as_string_fromval(val); byte * s = (byte *) as_string_tostring(v); size_t l = as_string_len(v); // Save for later. // cf_detail(AS_UDF, "udf_setbin: string: binname %s value is %s",bname,s); if ( !as_storage_bin_can_fit(rd->ns, l) ) { cf_warning(AS_UDF, "string: bin size too big"); ret = -1; break; } if (rd->ns->storage_data_in_memory) { as_particle_frombuf(b, AS_PARTICLE_TYPE_STRING, s, l, NULL, true); } else { pbytes = l + as_particle_get_base_size(AS_PARTICLE_TYPE_STRING); if ((urecord->cur_particle_data + pbytes) < urecord->end_particle_data) { as_particle_frombuf(b, AS_PARTICLE_TYPE_STRING, s, l, urecord->cur_particle_data, rd->ns->storage_data_in_memory); urecord->cur_particle_data += pbytes; } else { cf_warning(AS_UDF, "string: bin data size too big: pbytes %d" " pdata %p cur_part+pbytes %p pend %p", pbytes, urecord->particle_data, urecord->cur_particle_data + pbytes, urecord->end_particle_data); ret = -1; break; } } break; } case AS_BYTES: { as_bytes * v = as_bytes_fromval(val); uint8_t * s = as_bytes_get(v); size_t l = as_bytes_size(v); if ( !as_storage_bin_can_fit(rd->ns, l) ) { cf_warning(AS_UDF, "bytes: bin size too big"); ret = -1; break; } if (rd->ns->storage_data_in_memory) { as_particle_frombuf(b, AS_PARTICLE_TYPE_BLOB, s, l, NULL, true); } else { pbytes = l + as_particle_get_base_size(AS_PARTICLE_TYPE_BLOB); if ((urecord->cur_particle_data + pbytes) < urecord->end_particle_data) { as_particle_frombuf(b, AS_PARTICLE_TYPE_BLOB, s, l, urecord->cur_particle_data, rd->ns->storage_data_in_memory); urecord->cur_particle_data += pbytes; } else { cf_warning(AS_UDF, "bytes: bin data size too big pbytes %d" " pdata %p cur_part+pbytes %p pend %p", pbytes, urecord->particle_data, urecord->cur_particle_data + pbytes, urecord->end_particle_data); ret = -1; break; } } break; } case AS_BOOLEAN: { as_boolean * v = as_boolean_fromval(val); bool d = as_boolean_get(v); int64_t i = __be64_to_cpup((void *)&d); if ( !as_storage_bin_can_fit(rd->ns, 8) ) { cf_warning(AS_UDF, "bool: bin size too big"); ret = -1; break; } if (rd->ns->storage_data_in_memory) { as_particle_frombuf(b, AS_PARTICLE_TYPE_INTEGER, (uint8_t *) &i, 8, NULL, true); } else { pbytes = 8 + as_particle_get_base_size(AS_PARTICLE_TYPE_INTEGER); if ((urecord->cur_particle_data + pbytes) < urecord->end_particle_data) { as_particle_frombuf(b, AS_PARTICLE_TYPE_INTEGER, (uint8_t *) &i, 8, urecord->cur_particle_data, rd->ns->storage_data_in_memory); urecord->cur_particle_data += pbytes; } else { cf_warning(AS_UDF, "bool: bin data size too big: pbytes %d %p %p %p", pbytes, urecord->particle_data, urecord->cur_particle_data, urecord->end_particle_data); ret = -1; break; } } break; } case AS_INTEGER: { as_integer * v = as_integer_fromval(val); int64_t i = as_integer_get(v); int64_t j = __be64_to_cpup((void *)&i); if ( !as_storage_bin_can_fit(rd->ns, 8) ) { cf_warning(AS_UDF, "int: bin size too big"); ret = -1; break; } if (rd->ns->storage_data_in_memory) { as_particle_frombuf(b, AS_PARTICLE_TYPE_INTEGER, (uint8_t *) &j, 8, NULL, true); } else { pbytes = 8 + as_particle_get_base_size(AS_PARTICLE_TYPE_INTEGER); if ((urecord->cur_particle_data + pbytes) < urecord->end_particle_data) { as_particle_frombuf(b, AS_PARTICLE_TYPE_INTEGER, (uint8_t *) &j, 8, urecord->cur_particle_data, rd->ns->storage_data_in_memory); urecord->cur_particle_data += pbytes; } else { cf_warning(AS_UDF, "int: bin data size too big: pbytes %d %p %p %p", pbytes, urecord->particle_data, urecord->cur_particle_data, urecord->end_particle_data); ret = -1; break; } } break; } // @LDT : Possibly include AS_LDT in this list. We need the LDT // bins to be updated by LDT lua calls, and that path takes us thru here. // However, we ALSO need to be able to set the particle type for the // bins -- so that requires extra processing here to take the LDT flags // and set the appropriate bin flags in the particle data. case AS_MAP: case AS_LIST: { as_buffer buf; as_buffer_init(&buf); as_serializer s; as_msgpack_init(&s); int rsp = 0; as_serializer_serialize(&s, (as_val *) val, &buf); if ( !as_storage_bin_can_fit(rd->ns, buf.size) ) { cf_warning(AS_UDF, "map-list: bin size too big"); ret = -1; // Clean Up and jump out. as_serializer_destroy(&s); as_buffer_destroy(&buf); break; // can't continue if value too big. } uint8_t ptype; if(is_hidden) { ptype = as_particle_type_convert_to_hidden(to_particle_type(type)); } else { ptype = to_particle_type(type); } if (rd->ns->storage_data_in_memory) { as_particle_frombuf(b, ptype, (uint8_t *) buf.data, buf.size, NULL, true); } else { pbytes = buf.size + as_particle_get_base_size(ptype); if ((urecord->cur_particle_data + pbytes) < urecord->end_particle_data) { as_particle_frombuf(b, ptype, (uint8_t *) buf.data, buf.size, urecord->cur_particle_data, rd->ns->storage_data_in_memory); urecord->cur_particle_data += pbytes; } else { cf_warning(AS_UDF, "map-list: bin data size too big: pbytes %d %p %p %p", pbytes, urecord->particle_data, urecord->cur_particle_data, urecord->end_particle_data); rsp = -1; } } as_serializer_destroy(&s); as_buffer_destroy(&buf); if (rsp) { ret = rsp; break; } break; } default: { cf_warning(AS_UDF, "unrecognized object type %d, skipping", as_val_type(val) ); break; } } // If something fail bailout if (ret) { as_sindex_sbin_freeall(oldbin, 1); as_sindex_sbin_freeall(newbin, 1); return ret; } // Update sindex if required if (has_sindex) { if (as_sindex_sbin_from_bin(rd->ns, as_index_get_set_name(rd->r, rd->ns), b, newbin) == AS_SINDEX_OK) { if (!as_sindex_sbin_match(newbin, oldbin)) { needs_sindex_put = true; } else { needs_sindex_update = true; } } if (needs_sindex_update) { tr->flag |= AS_TRANSACTION_FLAG_SINDEX_TOUCHED; as_sindex_delete_by_sbin(rd->ns, as_index_get_set_name(rd->r, rd->ns), 1, oldbin, rd); as_sindex_put_by_sbin(rd->ns, as_index_get_set_name(rd->r, rd->ns), 1, newbin, rd); } else { if (needs_sindex_delete) { tr->flag |= AS_TRANSACTION_FLAG_SINDEX_TOUCHED; as_sindex_delete_by_sbin(rd->ns, as_index_get_set_name(rd->r, rd->ns), 1, oldbin, rd); } if (needs_sindex_put) { tr->flag |= AS_TRANSACTION_FLAG_SINDEX_TOUCHED; as_sindex_put_by_sbin(rd->ns, as_index_get_set_name(rd->r, rd->ns), 1, newbin, rd); } } as_sindex_sbin_freeall(oldbin, 1); as_sindex_sbin_freeall(newbin, 1); } return ret; } // end udf_aerospike_setbin()
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; }