/**
 * 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;
}
Example #2
0
bool
write_record(aerospike* p_as)
{
	as_error err;

	// Create an as_record object with four bins with different value types. By
	// using as_record_inita(), we won't need to destroy the record if we only
	// set bins using as_record_set_int64(), as_record_set_str(), and
	// as_record_set_raw().
	as_record rec;
	as_record_inita(&rec, 4);
	as_record_set_int64(&rec, "test-bin-1", 1111);
	as_record_set_int64(&rec, "test-bin-2", 2222);
	as_record_set_str(&rec, "test-bin-3", "test-bin-3-data");

	static const uint8_t bytes[] = { 1, 2, 3 };
	as_record_set_raw(&rec, "test-bin-4", bytes, 3);

	// Log its contents.
	LOG("as_record object to write to database:");
	example_dump_record(&rec);

	// Write the record to the database.
	if (aerospike_key_put(p_as, &err, NULL, &g_key, &rec) != AEROSPIKE_OK) {
		LOG("aerospike_key_put() returned %d - %s", err.code, err.message);
		return false;
	}

	LOG("write succeeded");

	return true;
}
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;
}
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;
}
bool
insert_records(aerospike* p_as)
{
	// Create an as_record object with one (integer value) bin. By using
	// as_record_inita(), we won't need to destroy the record if we only set
	// bins using as_record_set_int64().
	as_record rec;
	as_record_inita(&rec, 1);

	// Re-using rec, write records into the database such that each record's key
	// and (test-bin) value is based on the loop index.
	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);

		// In general it's ok to reset a bin value - all as_record_set_... calls
		// destroy any previous value.
		as_record_set_int64(&rec, "test-bin", (int64_t)i);

		// Write a record to the database.
		if (aerospike_key_put(p_as, &err, NULL, &key, &rec) != AEROSPIKE_OK) {
			LOG("aerospike_key_put() returned %d - %s", err.code, err.message);
			return false;
		}
	}

	LOG("insert succeeded");

	return true;
}
Example #6
0
bool
write_record(aerospike* p_as)
{
    as_error err;

    // Create an as_record object with two (integer type) bins. By using
    // as_record_inita(), we won't need to destroy the record if we only set
    // bins using as_record_set_int64().
    as_record rec;
    as_record_inita(&rec, 2);
    as_record_set_int64(&rec, "test-bin-1", 1000);
    as_record_set_int64(&rec, "test-bin-2", 1000);

    // Log its contents.
    LOG("as_record object to write to database:");
    example_dump_record(&rec);

    // Write the record to the database.
    if (aerospike_key_put(p_as, &err, NULL, &g_key, &rec) != AEROSPIKE_OK) {
        LOG("aerospike_key_put() returned %d - %s", err.code, err.message);
        return false;
    }

    LOG("write succeeded");

    return true;
}
Example #7
0
bool
insert_records(aerospike* p_as)
{
	// Create an as_record object with up to three integer value bins. By using
	// as_record_inita(), we won't need to destroy the record if we only set
	// bins using as_record_set_int64().
	as_record rec;
	as_record_inita(&rec, 3);

	// Re-using rec, write records into the database such that each record's key
	// and (test-bin) value is based on the loop index.
	for (uint32_t i = 0; i < g_n_keys; i++) {
		as_error err;

		// Set up a default as_policy_write object.
		as_policy_write wpol;
		as_policy_write_init(&wpol);

		// 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);

		// In general it's ok to reset a bin value - all as_record_set_... calls
		// destroy any previous value.

		if (i < 10) {
			// Only write one bin in the first ten records.
			as_record_set_int64(&rec, "test-bin-1", (int64_t)i);

			// By default, we don't store the key with the record in the
			// database. For these records, the key will not be returned in the
			// scan callback.
		}
		else {
			// Write three bins in all remaining records.
			as_record_set_int64(&rec, "test-bin-1", (int64_t)i);
			as_record_set_int64(&rec, "test-bin-2", (int64_t)(100 + i));
			as_record_set_int64(&rec, "test-bin-3", (int64_t)(1000 + i));

			// If we want the key to be returned in the scan callback, we must
			// store it with the record in the database. AS_POLICY_KEY_SEND
			// causes the key to be stored.
			wpol.key = AS_POLICY_KEY_SEND;
		}

		// Write a record to the database.
		if (aerospike_key_put(p_as, &err, &wpol, &key, &rec) != AEROSPIKE_OK) {
			LOG("aerospike_key_put() returned %d - %s", err.code, err.message);
			return false;
		}
	}

	LOG("insert succeeded");

	return true;
}
Example #8
0
static bool asc_raw_write(aerospike* p_as, as_key* p_key, uint8_t *buf, uint32_t size)
{
    as_error err;
    as_status status;

    uint32_t lstack_size = (size+(CHUNK_SIZE-1))/CHUNK_SIZE;
    uint32_t offset, chksize;

    // Create a large stack object to use
    as_ldt lstack;
	as_ldt_init(&lstack, "data", AS_LDT_LSTACK, NULL);

    // Make arraylist
    as_arraylist vals;
    as_arraylist_inita(&vals, lstack_size);

    as_bytes *p_bval;
    p_bval = (as_bytes *)alloca(lstack_size * sizeof(as_bytes));
    for (offset = 0; offset < size; offset += chksize, p_bval++) {
        chksize = MIN(size - offset, CHUNK_SIZE);
        as_bytes_init_wrap(p_bval, buf + offset, chksize, false);
        as_arraylist_insert_bytes(&vals, 0, p_bval);
    }

    // Push bytes
#if 1
    // FIXME it's a workaround
    uint32_t i;
    for (i = 0; i < vals.size; i++) {
        status = aerospike_lstack_push(p_as, &err, NULL, p_key, &lstack, vals.elements[i]);
        if (status != AEROSPIKE_OK) {
            ERROR("aerospike_lstack_push() - returned %d - %s", err.code, err.message);
            return false;
        }
    }
#else
    status = aerospike_lstack_push_all(p_as, &err, NULL, p_key, &lstack, (as_list *)&vals);
    if (status != AEROSPIKE_OK) {
        ERROR("aerospike_lstack_push_all() - returned %d - %s", err.code, err.message);
        return false;
    }
#endif

    // Write metadata
    as_record rec;
    as_record_inita(&rec, 1);
    as_record_set_int64(&rec, "size", size);
    aerospike_key_put(p_as, &err, NULL, p_key, &rec);

    return true;
}
/*
 *******************************************************************************************************
 * 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);
}
Example #10
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;
}
Example #11
0
static bool asc_raw_write(aerospike* p_as, as_key* p_key, uint8_t *buf, uint32_t size)
{
    as_status status;
    as_error err;

    // Prepare the record
    as_record rec;
    as_record_inita(&rec, 2);
    as_record_set_int64(&rec, "size", size);

    // Write the record to the database.
    as_record_set_raw(&rec, "data", (uint8_t *)buf, size);
    status = aerospike_key_put(p_as, &err, NULL, p_key, &rec);
    if (status != AEROSPIKE_OK) {
        ERROR("aerospike_key_put() returned %d - %s", err.code, err.message);
        return false;
    }

    return true;
}
Example #12
0
bool
insert_records(aerospike* p_as)
{
	srand((unsigned int)time(0));

	// Create an as_record object with an integer value bin, and a string value
	// bin, where the string is a list of comma-separated numbers. By using
	// as_record_inita(), we won't need to destroy the record if we only set
	// bins using as_record_set_int64() and as_record_set_str().
	as_record rec;
	as_record_inita(&rec, 2);

	// Re-using rec, write records into the database such that each record's key
	// and test-bin value is based on the loop index.
	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);

		// In general it's ok to reset a bin value - all as_record_set_... calls
		// destroy any previous value.
		as_record_set_int64(&rec, "test-bin", (int64_t)i);

		char numbers[(TOKENS_PER_BIN * 3) + 1];
		as_record_set_str(&rec, "numbers-bin", generate_numbers(numbers));

		// Write a record to the database.
		if (aerospike_key_put(p_as, &err, NULL, &key, &rec) != AEROSPIKE_OK) {
			LOG("aerospike_key_put() returned %d - %s", err.code, err.message);
			return false;
		}
	}

	LOG("insert succeeded");

	return true;
}
Example #13
0
bool
insert_records(aerospike* p_as)
{
	// Create an as_record object with one (GeoJSON value) bin. By using
	// as_record_inita(), we won't need to destroy the record if we only set
	// bins using as_record_set_geojson().
	as_record rec;
	as_record_inita(&rec, 1);

	// Re-using rec, write records into the database such that each record's key
	// and (test-bin) value is based on the loop index.
	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);

		double lng = -122 + (0.1 * i);
		double lat = 37.5 + (0.1 * i);
		char buff[1024];
		snprintf(buff, sizeof(buff),
				 "{ \"type\": \"Point\", \"coordinates\": [%f, %f] }", lng, lat);
		as_record_set_geojson_str(&rec, TEST_BIN_NAME, buff);

		// Write a record to the database.
		if (aerospike_key_put(p_as, &err, NULL, &key, &rec) != AEROSPIKE_OK) {
			LOG("aerospike_key_put() returned %d - %s", err.code, err.message);
			return false;
		}
	}

	LOG("insert succeeded");

	return true;
}
/**
 ******************************************************************************************************
 * 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);
}
Example #15
0
int
main(int argc, char* argv[])
{
	// Parse command line arguments.
	if (! example_get_opts(argc, argv, EXAMPLE_BASIC_OPTS)) {
		exit(-1);
	}

	// Connect to the aerospike database cluster.
	aerospike as;
	example_connect_to_aerospike(&as);

	// Start clean.
	example_remove_test_record(&as);

	as_error err;

	// Create an as_record object with one (integer value) bin. By using
	// as_record_inita(), we won't need to destroy the record if we only set
	// bins using as_record_set_int64().
	as_record rec;
	as_record_inita(&rec, 1);
	as_record_set_int64(&rec, "test-bin", 1234);

	// Set the TTL of the record so it will last a minute.
	rec.ttl = 60;

	// Log its contents.
	LOG("as_record object to write to database:");
	example_dump_record(&rec);

	// Write the record to the database.
	if (aerospike_key_put(&as, &err, NULL, &g_key, &rec) != AEROSPIKE_OK) {
		LOG("aerospike_key_put() returned %d - %s", err.code, err.message);
		example_cleanup(&as);
		exit(-1);
	}

	LOG("write succeeded");

	if (! example_read_test_record(&as)) {
		example_cleanup(&as);
		exit(-1);
	}

	// Create an as_operations object with a touch operation. Generally, if
	// using as_operations_inita(), we won't need to destroy the object unless
	// we call as_operations_add_write() with an externally allocated
	// as_bin_value.
	as_operations ops;
	as_operations_inita(&ops, 1);
	as_operations_add_touch(&ops);

	// Set the TTL of the record so it will last two minutes.
	ops.ttl = 120;

	// Log the operation.
	LOG("as_operations object to apply to database:");
	example_dump_operations(&ops);

	// Apply the operation. Note that it does increment the record generation.
	if (aerospike_key_operate(&as, &err, NULL, &g_key, &ops, NULL) !=
			AEROSPIKE_OK) {
		LOG("aerospike_key_operate() returned %d - %s", err.code, err.message);
		example_cleanup(&as);
		exit(-1);
	}

	LOG("operation succeeded");

	if (! example_read_test_record(&as)) {
		example_cleanup(&as);
		exit(-1);
	}

	// Cleanup and disconnect from the database cluster.
	example_cleanup(&as);

	LOG("touch example successfully completed");

	return 0;
}
Example #16
0
int
main(int argc, char* argv[])
{
	// Parse command line arguments.
	if (! example_get_opts(argc, argv, EXAMPLE_BASIC_OPTS)) {
		exit(-1);
	}

	// Connect to the aerospike database cluster.
	aerospike as;
	example_connect_to_aerospike(&as);

	// Start clean.
	example_remove_test_record(&as);

	as_error err;

	// Create an as_record object with two bins with different value types. By
	// using as_record_inita(), we won't need to destroy the record if we only
	// set bins using as_record_set_int64(), as_record_set_str(), and
	// as_record_set_nil().
	as_record rec;
	as_record_inita(&rec, 2);
	as_record_set_int64(&rec, "test-bin-1", 1234);
	as_record_set_str(&rec, "test-bin-2", "test-bin-2-data");

	// Log its contents.
	LOG("as_record object to write to database:");
	example_dump_record(&rec);

	// Write the record to the database.
	if (aerospike_key_put(&as, &err, NULL, &g_key, &rec) != AEROSPIKE_OK) {
		LOG("aerospike_key_put() returned %d - %s", err.code, err.message);
		example_cleanup(&as);
		exit(-1);
	}

	LOG("write succeeded");

	if (! example_read_test_record(&as)) {
		example_cleanup(&as);
		exit(-1);
	}

	// Generate a different as_record object to write. In general it's ok to
	// reuse the stack object by calling as_record_inita() again, as long as the
	// previous contents are destroyed if necessary.
	as_record_inita(&rec, 2);
	as_record_set_int64(&rec, "test-bin-2", 2222);
	as_record_set_str(&rec, "test-bin-3", "test-bin-3-data");

	// Log its contents.
	LOG("as_record object to write to database:");
	example_dump_record(&rec);

	// Write the record to the database. This will change the type and value of
	// test-bin-2, will add test-bin-3, and will leave test-bin-one unchanged.
	if (aerospike_key_put(&as, &err, NULL, &g_key, &rec) != AEROSPIKE_OK) {
		LOG("aerospike_key_put() returned %d - %s", err.code, err.message);
		example_cleanup(&as);
		exit(-1);
	}

	LOG("write succeeded");

	if (! example_read_test_record(&as)) {
		example_cleanup(&as);
		exit(-1);
	}

	// Generate another as_record object to write.
	as_record_inita(&rec, 1);
	as_record_set_nil(&rec, "test-bin-3");

	// Log its contents.
	LOG("as_record object to write to database:");
	example_dump_record(&rec);

	// Write the record to the database. This will remove test-bin-3 and
	// will leave test-bin-1 and test-bin-2 unchanged.
	if (aerospike_key_put(&as, &err, NULL, &g_key, &rec) != AEROSPIKE_OK) {
		LOG("aerospike_key_put() returned %d - %s", err.code, err.message);
		example_cleanup(&as);
		exit(-1);
	}

	LOG("write succeeded");

	if (! example_read_test_record(&as)) {
		example_cleanup(&as);
		exit(-1);
	}

	// Generate another as_record object to write.
	as_record_inita(&rec, 1);
	as_record_set_int64(&rec, "test-bin-1", 1111);

	// Require that the write succeeds only if the record doesn't exist.
	as_policy_write wpol;
	as_policy_write_init(&wpol);
	wpol.exists = AS_POLICY_EXISTS_CREATE;

	// Log its contents.
	LOG("as_record object to create in database:");
	example_dump_record(&rec);

	// Try to create the record. This should fail since the record already
	// exists in the database.
	if (aerospike_key_put(&as, &err, &wpol, &g_key, &rec) !=
			AEROSPIKE_ERR_RECORD_EXISTS) {
		LOG("aerospike_key_put() returned %d - %s, expected "
				"AEROSPIKE_ERR_RECORD_EXISTS", err.code, err.message);
		example_cleanup(&as);
		exit(-1);
	}

	LOG("create failed as expected");

	// Remove the record from the database so we can demonstrate create success.
	if (aerospike_key_remove(&as, &err, NULL, &g_key) != AEROSPIKE_OK) {
		LOG("aerospike_key_remove() returned %d - %s", err.code, err.message);
		example_cleanup(&as);
		exit(-1);
	}

	LOG("record removed from database, trying create again");

	// Try to create the record again. This should succeed since the record is
	// not currently in the database.
	if (aerospike_key_put(&as, &err, &wpol, &g_key, &rec) !=
			AEROSPIKE_OK) {
		LOG("aerospike_key_put() returned %d - %s", err.code, err.message);
		example_cleanup(&as);
		exit(-1);
	}

	LOG("create succeeded");

	if (! example_read_test_record(&as)) {
		example_cleanup(&as);
		exit(-1);
	}

	// Cleanup and disconnect from the database cluster.
	example_cleanup(&as);

	LOG("put example successfully completed");

	return 0;
}
Example #17
0
int
main(int argc, char* argv[])
{
	// Parse command line arguments.
	if (! example_get_opts(argc, argv, EXAMPLE_BASIC_OPTS)) {
		exit(-1);
	}

	// Connect to the aerospike database cluster.
	aerospike as;
	example_connect_to_aerospike(&as);

	// Start clean.
	example_remove_test_record(&as);

	as_error err;

	// Create an as_record object with one (integer value) bin. By using
	// as_record_inita(), we won't need to destroy the record if we only set
	// bins using as_record_set_int64().
	as_record rec;
	as_record_inita(&rec, 1);
	as_record_set_int64(&rec, TEST_BIN, 1001);

	// Log its contents.
	LOG("as_record object to write to database:");
	example_dump_record(&rec);

	// Write the record to the database. If the record isn't already in the
	// database, it will be created with generation = 1.
	if (aerospike_key_put(&as, &err, NULL, &g_key, &rec) != AEROSPIKE_OK) {
		LOG("aerospike_key_put() returned %d - %s", err.code, err.message);
		example_cleanup(&as);
		exit(-1);
	}

	LOG("write succeeded");

	uint16_t gen;

	// Read the record back, and get its generation.
	if (! read_generation(&as, &gen)) {
		example_cleanup(&as);
		exit(-1);
	}

	// Update the as_record object with a different bin value. In general it's
	// ok to do this - all as_record_set_... calls destroy any previous value.
	as_record_set_int64(&rec, TEST_BIN, 1002);

	// Set its generation equal to that of the record in the database.
	rec.gen = gen;

	// Require that the next write will only succeed if generations match.
	as_policy_write wpol;
	as_policy_write_init(&wpol);
	wpol.gen = AS_POLICY_GEN_EQ;

	// Log its contents.
	LOG("as_record object to write to database:");
	example_dump_record(&rec);

	// Re-write the record in the database. The write should succeed, and
	// increment the generation.
	if (aerospike_key_put(&as, &err, &wpol, &g_key, &rec) != AEROSPIKE_OK) {
		LOG("aerospike_key_put() returned %d - %s", err.code, err.message);
		example_cleanup(&as);
		exit(-1);
	}

	LOG("re-write requiring generation = %u succeeded", rec.gen);

	// Read the record back, and get its generation.
	if (! read_generation(&as, &gen)) {
		example_cleanup(&as);
		exit(-1);
	}

	// Update the record object with a different bin value.
	as_record_set_int64(&rec, TEST_BIN, 1003);

	// Set its generation way past that of the record in the database.
	rec.gen = gen + 10;

	// Log its contents.
	LOG("as_record object to write to database:");
	example_dump_record(&rec);

	// Try to re-write the record in the database. Use the same write policy,
	// requiring generations to match. This write should fail.
	if (aerospike_key_put(&as, &err, &wpol, &g_key, &rec) !=
			AEROSPIKE_ERR_RECORD_GENERATION) {
		LOG("aerospike_key_put() returned %d - %s, expected "
				"AEROSPIKE_ERR_RECORD_GENERATION", err.code, err.message);
		example_cleanup(&as);
		exit(-1);
	}

	LOG("re-write requiring generation = %u failed as expected", rec.gen);

	// Now require that the next write will only succeed if the specified
	// generation is greater than that of the record in the database.
	wpol.gen = AS_POLICY_GEN_GT;

	// Log its contents.
	LOG("as_record object to write to database:");
	example_dump_record(&rec);

	// Try again. This write should succeed, and increment the generation. (Note
	// that it does not write the record with the local generation!)
	if (aerospike_key_put(&as, &err, &wpol, &g_key, &rec) != AEROSPIKE_OK) {
		LOG("aerospike_key_put() returned %d - %s", err.code, err.message);
		example_cleanup(&as);
		exit(-1);
	}

	LOG("re-write requiring generation < %u succeeded", rec.gen);

	// Read the record back, and get its generation.
	if (! read_generation(&as, &gen)) {
		example_cleanup(&as);
		exit(-1);
	}

	// Cleanup and disconnect from the database cluster.
	example_cleanup(&as);

	LOG("generation example successfully completed");

	return 0;
}
Example #18
0
int
main(int argc, char* argv[])
{
	// Parse command line arguments.
	if (! example_get_opts(argc, argv, EXAMPLE_BASIC_OPTS)) {
		exit(-1);
	}

	// Connect to the aerospike database cluster.
	aerospike as;
	example_connect_to_aerospike(&as);

	// Start clean.
	example_remove_test_record(&as);

	as_error err;

	// Create an as_operations object with a pair of bin arithmetic operations.
	// Generally, if using as_operations_inita(), we won't need to destroy the
	// object unless we call as_operations_add_write() with an externally
	// allocated as_bin_value.
	as_operations ops;
	as_operations_inita(&ops, 2);
	as_operations_add_incr(&ops, "test-bin-1", 1001);
	as_operations_add_incr(&ops, "test-bin-2", 1002);

	// Log the operations.
	LOG("as_operations object to apply to database:");
	example_dump_operations(&ops);

	// Apply the operations. Since the record does not exist, it will be created
	// and the bins initialized with the ops' integer values.
	if (aerospike_key_operate(&as, &err, NULL, &g_key, &ops, NULL) !=
			AEROSPIKE_OK) {
		LOG("aerospike_key_operate() returned %d - %s", err.code, err.message);
		example_cleanup(&as);
		exit(-1);
	}

	LOG("operations succeeded");

	if (! example_read_test_record(&as)) {
		example_cleanup(&as);
		exit(-1);
	}

	// Generate a different set of arithmetic operations.
	as_operations_inita(&ops, 3);
	as_operations_add_incr(&ops, "test-bin-1", 1);
	as_operations_add_incr(&ops, "test-bin-2", -2);
	as_operations_add_incr(&ops, "test-bin-3", 3);

	// Log the operations.
	LOG("as_operations object to apply to database:");
	example_dump_operations(&ops);

	// Apply the operations. The first two bins exist, so those ops' values will
	// be added to the existing values. The third (non-existent) bin will be
	// created and initialized with the op's integer value.
	if (aerospike_key_operate(&as, &err, NULL, &g_key, &ops, NULL) !=
			AEROSPIKE_OK) {
		LOG("aerospike_key_operate() returned %d - %s", err.code, err.message);
		example_cleanup(&as);
		exit(-1);
	}

	LOG("operations succeeded");

	if (! example_read_test_record(&as)) {
		example_cleanup(&as);
		exit(-1);
	}

	// Create an as_record object with one string value bin.
	as_record rec;
	as_record_inita(&rec, 1);
	as_record_set_str(&rec, "test-bin-1", "test-bin-1-data");

	// Log its contents.
	LOG("as_record object to write to database:");
	example_dump_record(&rec);

	// Write the record to the database, to change the value type of the bin.
	if (aerospike_key_put(&as, &err, NULL, &g_key, &rec) != AEROSPIKE_OK) {
		LOG("aerospike_key_put() returned %d - %s", err.code, err.message);
		example_cleanup(&as);
		exit(-1);
	}

	LOG("write succeeded");

	if (! example_read_test_record(&as)) {
		example_cleanup(&as);
		exit(-1);
	}

	// Log the operations. (Same operations as last time.)
	LOG("as_operations object to apply to database:");
	example_dump_operations(&ops);

	// Try to apply the three arithmetic operations again. This will fail, since
	// we can't increment the string value. Note that if any operation in the
	// transaction is rejected, none will be applied.
	if (aerospike_key_operate(&as, &err, NULL, &g_key, &ops, NULL) !=
			AEROSPIKE_ERR_BIN_INCOMPATIBLE_TYPE) {
		LOG("aerospike_key_operate() returned %d - %s, expected "
				"AEROSPIKE_ERR_BIN_INCOMPATIBLE_TYPE", err.code, err.message);
		example_cleanup(&as);
		exit(-1);
	}

	LOG("operations failed as expected");

	if (! example_read_test_record(&as)) {
		example_cleanup(&as);
		exit(-1);
	}

	// Generate a pair of operations to do an atomic increment and read.
	as_operations_inita(&ops, 2);
	as_operations_add_incr(&ops, "test-bin-3", 1);
	as_operations_add_read(&ops, "test-bin-3");

	// Log the operations.
	LOG("as_operations object to apply to database:");
	example_dump_operations(&ops);

	as_record* p_rec = NULL;

	// Apply the operations. The first will add the op's value to the existing
	// value, and the second will return the result. The pair of operations will
	// be atomic on the server.
	if (aerospike_key_operate(&as, &err, NULL, &g_key, &ops, &p_rec) !=
			AEROSPIKE_OK) {
		LOG("aerospike_key_operate() returned %d - %s", err.code, err.message);
		example_cleanup(&as);
		exit(-1);
	}

	LOG("operations succeeded");

	example_dump_record(p_rec);
	as_record_destroy(p_rec);

	if (! example_read_test_record(&as)) {
		example_cleanup(&as);
		exit(-1);
	}

	// Cleanup and disconnect from the database cluster.
	example_cleanup(&as);

	LOG("incr example successfully completed");

	return 0;
}