Пример #1
0
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;
}
Пример #2
0
// ----------------------------------------------------------------------------------
//
// 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;
}
Пример #3
0
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;
}
Пример #4
0
// ----------------------------------------------------------------------------------
//
// 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;
}
Пример #5
0
//------------------------------------------------
// 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;
}
Пример #6
0
/**
 * 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;
}
Пример #7
0
// 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);
}
Пример #8
0
// ----------------------------------------------------------------------------------
//
// 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;
}
Пример #9
0
// 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);
}
Пример #10
0
// ----------------------------------------------------------------------------------
//
// 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);
}
Пример #12
0
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;
}
Пример #13
0
// ----------------------------------------------------------------------------------
//
// 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;
}
Пример #14
0
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;
}
Пример #15
0
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;

}
Пример #16
0
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;
}
Пример #17
0
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);   
}
Пример #19
0
//------------------------------------------------
// 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;
}
Пример #20
0
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;
}
Пример #21
0
/**
 * 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;
}
Пример #22
0
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);
}
Пример #23
0
/**
 * 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;
}
Пример #24
0
/**
 *******************************************************************************************************
 * 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;
}
Пример #25
0
/**
 * 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;
}
Пример #26
0
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;
}
Пример #27
0
/**
 ******************************************************************************************************
 * 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);
}
Пример #28
0
SourceRecord::~SourceRecord()
{
	if (record_) {
		as_record_destroy(record_);
	}
}
Пример #29
0
/**
 *******************************************************************************************************
 * 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);
	}
}
Пример #30
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);
}