Ejemplo n.º 1
0
as_record * SourceRecord::record()
{
	if (!record_) {
		record_ = as_record_new(11);

		as_record_set_int64(record_, "latest_time", time_);
		as_record_set_str(record_, "adv_id", advId_.c_str());
		as_record_set_str(record_, "sid", sid_.c_str());
		as_record_set_str(record_, "adx_id", adxId_.c_str());
		as_record_set_str(record_, "mt_uid", mtUid_.c_str());
		as_record_set_str(record_, "pid", pid_.c_str());
		as_record_set_str(record_, "request_id", requestId_.c_str());
		as_record_set_str(record_, "create_id", createId_.c_str());
		as_record_set_str(record_, "geo_id", geoId_.c_str());
		as_record_set_str(record_, "referer_url", refererUrl_.c_str());
		as_record_set_str(record_, "bid_price", bidPrice_.c_str());
	}

	return record_;
}
Ejemplo n.º 2
0
/**
 *	Look up a record by key, then return all bins.
 *	
 *	@param as			The aerospike instance to use for this operation.
 *	@param err			The as_error to be populated if an error occurs.
 *	@param policy		The policy to use for this operation. If NULL, then the default policy will be used.
 *	@param key			The key of the record.
 *	@param rec 			The record to be populated with the data from request.
 *
 *	@return AEROSPIKE_OK if successful. Otherwise an error.
 */
as_status aerospike_key_get(
	aerospike * as, as_error * err, const as_policy_read * policy, 
	const as_key * key, 
	as_record ** rec) 
{
	// we want to reset the error so, we have a clean state
	as_error_reset(err);
	
	// resolve policies
	as_policy_read p;
	as_policy_read_resolve(&p, &as->config.policies, policy);

	uint32_t    timeout = p.timeout == UINT32_MAX ? 0 : p.timeout;          
	uint32_t    gen = 0;
	uint32_t 	ttl = 0;
	int         nvalues = 0;
	cl_bin *    values = NULL;

	cl_rv rc = CITRUSLEAF_OK;

	switch ( p.key ) {
		case AS_POLICY_KEY_DIGEST: {
			as_digest * digest = as_key_digest((as_key *) key);
			rc = citrusleaf_get_all_digest_getsetname(as->cluster, key->ns, (cf_digest *) digest->value,
					&values, &nvalues, timeout, &gen, NULL, &ttl);
			break;
		}
		case AS_POLICY_KEY_SEND: {
			cl_object okey;
			asval_to_clobject((as_val *) key->valuep, &okey);
			as_digest * digest = as_key_digest((as_key *) key);
			rc = citrusleaf_get_all(as->cluster, key->ns, key->set, &okey, (cf_digest*)digest->value,
					&values, &nvalues, timeout, &gen, &ttl);
			break;
		}
		default: {
			// ERROR CASE
			break;
		}
	}
	
	if ( rc == CITRUSLEAF_OK && rec != NULL ) {
		as_record * r = *rec;
		if ( r == NULL ) {
			r = as_record_new(0);
		}
		if ( r->bins.entries == NULL ) {
			r->bins.capacity = nvalues;
			r->bins.size = 0;
			r->bins.entries = malloc(sizeof(as_bin) * nvalues);
			r->bins._free = true;
		}
		clbins_to_asrecord(values, nvalues, r);
		r->gen = (uint16_t) gen;
		r->ttl = ttl;
		*rec = r;
	}

	if ( values != NULL ) {
		// We are freeing the bins' objects, as opposed to bins themselves.
		citrusleaf_bins_free(values, nvalues);
		free(values);
	}

	return as_error_fromrc(err,rc);
}
Ejemplo n.º 3
0
/**
 *	Lookup a record by key, then perform specified operations.
 *
 *	~~~~~~~~~~{.c}
 *		as_key key;
 *		as_key_init(&key, "ns", "set", "key");
 *
 *		as_operations ops;
 *		as_operations_inita(&ops,2);
 *		as_operations_append_int64(&ops, AS_OPERATOR_INCR, "bin1", 456);
 *		as_operations_append_str(&ops, AS_OPERATOR_APPEND, "bin1", "def");
 *
 *		if ( aerospike_key_remove(&as, &err, NULL, &key, &ops) != AEROSPIKE_OK ) {
 *			fprintf(stderr, "error(%d) %s at [%s:%d]", err.code, err.message, err.file, err.line);
 *		}
 *	~~~~~~~~~~
 *	
 *	@param as			The aerospike instance to use for this operation.
 *	@param err			The as_error to be populated if an error occurs.
 *	@param policy		The policy to use for this operation. If NULL, then the default policy will be used.
 *	@param key			The key of the record.
 *	@param ops			The operations to perform on the record.
 *	@param rec			The record to be populated with the data from AS_OPERATOR_READ operations.
 *
 *	@return AEROSPIKE_OK if successful. Otherwise an error.
 */
as_status aerospike_key_operate(
	aerospike * as, as_error * err, const as_policy_operate * policy, 
	const as_key * key, const as_operations * ops,
	as_record ** rec)
{
	// we want to reset the error so, we have a clean state
	as_error_reset(err);
	
	// resolve policies
	as_policy_operate p;
	as_policy_operate_resolve(&p, &as->config.policies, policy);

	cl_write_parameters wp;
	aspolicyoperate_to_clwriteparameters(&p, ops, &wp);

	uint32_t 		gen = 0;
	uint32_t 		ttl = 0;
	int 			n_operations = ops->binops.size;
	cl_operation * 	operations = (cl_operation *) alloca(sizeof(cl_operation) * n_operations);
	int				n_read_ops = 0;
	as_bin_name *	read_op_bins = alloca(sizeof(as_bin_name) * n_operations);

	for(int i=0; i<n_operations; i++) {
		cl_operation * clop = &operations[i];
		as_binop * op = &ops->binops.entries[i];

		// Length check already done on as_bin name length. For performance we
		// we'll leave out this down-size check since this is a temporary shim
		// and we know the CL and AS limits are the same...
//		if ( strlen(op->bin.name) > CL_BINNAME_SIZE - 1 ) {
//			return as_error_update(err, AEROSPIKE_ERR_PARAM, "bin name too long: %s", op->bin.name);
//		}

		strcpy(clop->bin.bin_name, op->bin.name);
		clop->op = (cl_operator)op->op;

		// Collect bin names that are read.
		if (op->op == AS_OPERATOR_READ) {
			strcpy(read_op_bins[n_read_ops++], op->bin.name);
		}

		asbinvalue_to_clobject(op->bin.valuep, &clop->bin.object);
	}

	cl_rv rc = CITRUSLEAF_OK;

	switch ( p.key ) {
		case AS_POLICY_KEY_DIGEST: {
			as_digest * digest = as_key_digest((as_key *) key);
			rc = citrusleaf_operate_digest(as->cluster, key->ns, key->set, (cf_digest *) digest->value,
					operations, n_operations, &wp, &gen, &ttl);
			break;
		}
		case AS_POLICY_KEY_SEND: {
			cl_object okey;
			asval_to_clobject((as_val *) key->valuep, &okey);
			as_digest * digest = as_key_digest((as_key *) key);
			rc = citrusleaf_operate(as->cluster, key->ns, key->set, &okey, (cf_digest*)digest->value,
					operations, n_operations, &wp, &gen, &ttl);
			break;
		}
		default: {
			// ERROR CASE
			break;
		}
	}

	if ( n_read_ops != 0 && rc == CITRUSLEAF_OK && rec != NULL ) {
		as_record * r = *rec;
		if ( r == NULL ) {
			r = as_record_new(0);
		}
		if ( r->bins.entries == NULL ) {
			r->bins.capacity = n_read_ops;
			r->bins.size = 0;
			r->bins.entries = malloc(sizeof(as_bin) * n_read_ops);
			r->bins._free = true;
		}
		r->gen = (uint16_t) gen;
		r->ttl = ttl;

		// This works around an existing client bug where the data returned for
		// a read operation is stored in the first bin struct with that bin
		// name, not necessarily the bin struct corresponding to the read.
		for (int i = 0; i < n_read_ops; i++) {
			for (int j = 0; j < n_operations; j++) {
				if (strcmp(read_op_bins[i], operations[j].bin.bin_name) == 0) {
					clbin_to_asrecord(&operations[j].bin, r);
					citrusleaf_object_free(&operations[j].bin.object);
					break;
				}
			}
		}

		*rec = r;
	}

	return as_error_fromrc(err,rc);
}
Ejemplo n.º 4
0
/**
 *	Check if a record exists in the cluster via its key.
 *	
 *	@param as			The aerospike instance to use for this operation.
 *	@param err			The as_error to be populated if an error occurs.
 *	@param policy		The policy to use for this operation. If NULL, then the default policy will be used.
 *	@param key			The key of the record.
 *	@param record       The record to populated with metadata if record exists, otherwise NULL
 *
 *	@return AEROSPIKE_OK if successful. Otherwise an error.
 */
as_status aerospike_key_exists(
	aerospike * as, as_error * err, const as_policy_read * policy, 
	const as_key * key, 
	as_record ** rec) 
{
	// we want to reset the error so, we have a clean state
	as_error_reset(err);
	
	// resolve policies
	as_policy_read p;
	as_policy_read_resolve(&p, &as->config.policies, policy);

	uint32_t	timeout = p.timeout == UINT32_MAX ? 0 : p.timeout;
	uint32_t	gen = 0;
	uint32_t	ttl = 0; // TODO - a version of 'exists' that returns all metadata
	int     	nvalues = 0;
	cl_bin *	values = NULL;
	
	cl_rv rc = CITRUSLEAF_OK;

	switch ( p.key ) {
		case AS_POLICY_KEY_DIGEST: {
			as_digest * digest = as_key_digest((as_key *) key);
			rc = citrusleaf_exists_digest(as->cluster, key->ns, (cf_digest *) digest->value,
					values, nvalues, timeout, &gen, &ttl);
			break;
		}
		case AS_POLICY_KEY_SEND: {
			cl_object okey;
			asval_to_clobject((as_val *) key->valuep, &okey);
			as_digest * digest = as_key_digest((as_key *) key);
			rc = citrusleaf_exists_key(as->cluster, key->ns, key->set, &okey, (cf_digest*)digest->value,
					values, nvalues, timeout, &gen, &ttl);
			break;
		}
		default: {
			// ERROR CASE
			break;
		}
	}

	if ( values != NULL ) {
		// We are freeing the bins' objects, as opposed to bins themselves.
		citrusleaf_bins_free(values, nvalues);
		free(values);
	}

	switch(rc) {
		case CITRUSLEAF_OK: 
			{
				as_record * r = *rec;
				if ( r == NULL ) { 
					r = as_record_new(0);
				}   
				r->gen = (uint16_t) gen;
				r->ttl = ttl;
				*rec = r;
				break;
			}

		default:
			*rec = NULL;
			break;
	}

	return as_error_fromrc(err,rc);
}
Ejemplo n.º 5
0
/**
 *	Lookup a record by key, then return specified bins.
 *	
 *	@param as			The aerospike instance to use for this operation.
 *	@param err			The as_error to be populated if an error occurs.
 *	@param policy		The policy to use for this operation. If NULL, then the default policy will be used.
 *	@param key			The key of the record.
 *	@param bins			The bins to select. A NULL terminated array of NULL terminated strings.
 *	@param rec 			The record to be populated with the data from request.
 *
 *	@return AEROSPIKE_OK if successful. Otherwise an error.
 */
as_status aerospike_key_select(
	aerospike * as, as_error * err, const as_policy_read * policy, 
	const as_key * key, const char * bins[], 
	as_record ** rec) 
{
	// we want to reset the error so, we have a clean state
	as_error_reset(err);
	
	// resolve policies
	as_policy_read p;
	as_policy_read_resolve(&p, &as->config.policies, policy);

	uint32_t    timeout = p.timeout == UINT32_MAX ? 0 : p.timeout;
	uint32_t    gen = 0;
	uint32_t 	ttl = 0;
	int         nvalues = 0;
	cl_bin *    values = NULL;

	for (nvalues = 0; bins[nvalues] != NULL && bins[nvalues][0] != '\0'; nvalues++)
		;

	values = (cl_bin *) alloca(sizeof(cl_bin) * nvalues);
	for ( int i = 0; i < nvalues; i++ ) {
		if ( strlen(bins[i]) > AS_BIN_NAME_MAX_LEN ) {
			return as_error_update(err, AEROSPIKE_ERR_PARAM, "bin name too long: %s", bins[i]);
		}

		strcpy(values[i].bin_name, bins[i]);
		citrusleaf_object_init(&values[i].object);
	}

	cl_rv rc = CITRUSLEAF_OK;

	switch ( p.key ) {
		case AS_POLICY_KEY_DIGEST: {
			as_digest * digest = as_key_digest((as_key *) key);
			rc = citrusleaf_get_digest(as->cluster, key->ns, (cf_digest *) digest->value,
					values, nvalues, timeout, &gen, &ttl);
			break;
		}
		case AS_POLICY_KEY_SEND: {
			cl_object okey;
			asval_to_clobject((as_val *) key->valuep, &okey);
			as_digest * digest = as_key_digest((as_key *) key);
			rc = citrusleaf_get(as->cluster, key->ns, key->set, &okey, (cf_digest*)digest->value,
					values, nvalues, timeout, &gen, &ttl);
			break;
		}
		default: {
			// ERROR CASE
			break;
		}
	}

	if ( rc == CITRUSLEAF_OK && rec != NULL ) {
		as_record * r = *rec;
		if ( r == NULL ) {
			r = as_record_new(0);
		}
		if ( r->bins.entries == NULL ) {
			r->bins.capacity = nvalues;
			r->bins.size = 0;
			r->bins.entries = malloc(sizeof(as_bin) * nvalues);
			r->bins._free = true;
		}
		clbins_to_asrecord(values, nvalues, r);
		r->gen = (uint16_t) gen;
		r->ttl = ttl;
		*rec = r;
	}

	if ( values != NULL ) {
		// We are freeing the bins' objects, as opposed to bins themselves.
		citrusleaf_bins_free(values, nvalues);
	}

	return as_error_fromrc(err,rc);
}
Ejemplo n.º 6
0
as_status
as_command_parse_result(as_error* err, int fd, uint64_t deadline_ms, void* user_data)
{
    // Read header
    as_proto_msg msg;
    as_status status = as_socket_read_deadline(err, fd, (uint8_t*)&msg, sizeof(as_proto_msg), deadline_ms);

    if (status) {
        return status;
    }

    as_proto_swap_from_be(&msg.proto);
    as_msg_swap_header_from_be(&msg.m);
    size_t size = msg.proto.sz  - msg.m.header_sz;
    uint8_t* buf = 0;

    if (size > 0) {
        // Read remaining message bytes.
        buf = as_command_init(size);
        status = as_socket_read_deadline(err, fd, buf, size, deadline_ms);

        if (status) {
            as_command_free(buf, size);
            return status;
        }
    }

    // Parse result code and record.
    status = msg.m.result_code;
    as_command_parse_result_data* data = user_data;

    switch (status) {
    case AEROSPIKE_OK: {
        if (data->record) {
            as_record* rec = *data->record;

            if (rec) {
                if (msg.m.n_ops > rec->bins.capacity) {
                    if (rec->bins._free) {
                        free(rec->bins.entries);
                    }
                    rec->bins.capacity = msg.m.n_ops;
                    rec->bins.size = 0;
                    rec->bins.entries = malloc(sizeof(as_bin) * msg.m.n_ops);
                    rec->bins._free = true;
                }
            }
            else {
                rec = as_record_new(msg.m.n_ops);
                *data->record = rec;
            }
            rec->gen = msg.m.generation;
            rec->ttl = cf_server_void_time_to_ttl(msg.m.record_ttl);

            uint8_t* p = as_command_ignore_fields(buf, msg.m.n_fields);
            as_command_parse_bins(rec, p, msg.m.n_ops, data->deserialize);
        }
        break;
    }

    case AEROSPIKE_ERR_UDF: {
        status = as_command_parse_udf_failure(buf, err, &msg.m, status);
        break;
    }

    default:
        as_error_set_message(err, status, as_error_string(status));
        break;
    }
    as_command_free(buf, size);
    return status;
}