static size_t
as_scan_command_init(uint8_t* cmd, const as_policy_scan* policy, const as_scan* scan,
	uint64_t task_id, uint16_t n_fields, as_buffer* argbuffer)
{
	uint8_t* p;
	
	if (scan->apply_each.function[0]) {
		p = as_command_write_header(cmd, AS_MSG_INFO1_READ, AS_MSG_INFO2_WRITE,
			AS_POLICY_COMMIT_LEVEL_ALL, AS_POLICY_CONSISTENCY_LEVEL_ONE, AS_POLICY_EXISTS_IGNORE,
			AS_POLICY_GEN_IGNORE, 0, 0, policy->timeout, n_fields, 0);
	}
	else {
		uint8_t read_attr = (scan->no_bins)? AS_MSG_INFO1_READ | AS_MSG_INFO1_GET_NOBINDATA : AS_MSG_INFO1_READ;
		p = as_command_write_header_read(cmd, read_attr, AS_POLICY_CONSISTENCY_LEVEL_ONE, policy->timeout, n_fields, scan->select.size);
	}
	
	if (scan->ns) {
		p = as_command_write_field_string(p, AS_FIELD_NAMESPACE, scan->ns);
	}
	
	if (scan->set) {
		p = as_command_write_field_string(p, AS_FIELD_SETNAME, scan->set);
	}
	
	// Write scan options
	p = as_command_write_field_header(p, AS_FIELD_SCAN_OPTIONS, 2);
	uint8_t priority = scan->priority << 4;
	
	if (policy->fail_on_cluster_change) {
		priority |= 0x08;
	}
	*p++ = priority;
	*p++ = scan->percent;
	
	// Write taskId field
	p = as_command_write_field_uint64(p, AS_FIELD_TASK_ID, task_id);
	
	// Write background function
	if (scan->apply_each.function[0]) {
		p = as_command_write_field_header(p, AS_FIELD_UDF_OP, 1);
		*p++ = 2;
		p = as_command_write_field_string(p, AS_FIELD_UDF_PACKAGE_NAME, scan->apply_each.module);
		p = as_command_write_field_string(p, AS_FIELD_UDF_FUNCTION, scan->apply_each.function);
		p = as_command_write_field_buffer(p, AS_FIELD_UDF_ARGLIST, argbuffer);
	}
    as_buffer_destroy(argbuffer);
	
	if (scan->select.size > 0) {
		for (uint16_t i = 0; i < scan->select.size; i++) {
			p = as_command_write_bin_name(p, scan->select.entries[i]);
		}
	}
	return as_command_write_end(cmd, p);
}
Esempio n. 2
0
static uint8_t*
as_command_write_user_key(uint8_t* begin, const as_key* key)
{
    uint8_t* p = begin + AS_FIELD_HEADER_SIZE;
    as_val* val = (as_val*)key->valuep;
    uint32_t len;

    // Key must not be list or map.
    switch (val->type) {
    default:
    case AS_NIL: {
        *p++ = AS_BYTES_UNDEF;
        len = 0;
        break;
    }
    case AS_INTEGER: {
        as_integer* v = as_integer_fromval(val);
        *p++ = AS_BYTES_INTEGER;
        *(uint64_t*)p = cf_swap_to_be64(v->value);
        p += 8;
        len = 8;
        break;
    }
    case AS_DOUBLE: {
        as_double* v = as_double_fromval(val);
        *p++ = AS_BYTES_DOUBLE;
        *(double*)p = cf_swap_to_big_float64(v->value);
        p += 8;
        len = 8;
        break;
    }
    case AS_STRING: {
        as_string* v = as_string_fromval(val);
        *p++ = AS_BYTES_STRING;
        // v->len should have been already set when calculating the digest.
        memcpy(p, v->value, v->len);
        p += v->len;
        len = (uint32_t)v->len;
        break;
    }
    case AS_BYTES: {
        as_bytes* v = as_bytes_fromval(val);
        // Note: v->type must be a blob type (AS_BYTES_BLOB, AS_BYTES_JAVA, AS_BYTES_PYTHON ...).
        // Otherwise, the particle type will be reassigned to a non-blob which causes a
        // mismatch between type and value.
        *p++ = v->type;
        memcpy(p, v->value, v->size);
        p += v->size;
        len = v->size;
        break;
    }
    }
    as_command_write_field_header(begin, AS_FIELD_KEY, ++len);
    return p;
}
static size_t
as_scan_command_init(uint8_t* cmd, const as_policy_scan* policy, const as_scan* scan,
uint64_t task_id, uint16_t n_fields, as_buffer* argbuffer, uint32_t predexp_size)
{
	uint8_t* p;
	
	if (scan->apply_each.function[0]) {
		p = as_command_write_header(cmd, AS_MSG_INFO1_READ, AS_MSG_INFO2_WRITE, 0,
			AS_POLICY_COMMIT_LEVEL_ALL, AS_POLICY_EXISTS_IGNORE, AS_POLICY_GEN_IGNORE, 0, 0,
			policy->base.total_timeout, n_fields, 0, policy->durable_delete);
	}
	else {
		uint8_t read_attr = (scan->no_bins)? AS_MSG_INFO1_READ | AS_MSG_INFO1_GET_NOBINDATA : AS_MSG_INFO1_READ;
		p = as_command_write_header_read(cmd, read_attr, AS_POLICY_READ_MODE_AP_ONE,
			AS_POLICY_READ_MODE_SC_SESSION, policy->base.total_timeout, n_fields, scan->select.size);
	}
	
	if (scan->ns[0]) {
		p = as_command_write_field_string(p, AS_FIELD_NAMESPACE, scan->ns);
	}
	
	if (scan->set[0]) {
		p = as_command_write_field_string(p, AS_FIELD_SETNAME, scan->set);
	}

	// Write scan options
	p = as_command_write_field_header(p, AS_FIELD_SCAN_OPTIONS, 2);
	uint8_t priority = scan->priority << 4;
	
	if (policy->fail_on_cluster_change) {
		priority |= 0x08;
	}

	*p++ = priority;
	*p++ = scan->percent;

	// Write socket timeout.
	p = as_command_write_field_header(p, AS_FIELD_SCAN_TIMEOUT, sizeof(uint32_t));
	*(uint32_t*)p = cf_swap_to_be32(policy->base.socket_timeout);
	p += sizeof(uint32_t);

	// Write taskId field
	p = as_command_write_field_uint64(p, AS_FIELD_TASK_ID, task_id);
	
	// Write background function
	if (scan->apply_each.function[0]) {
		p = as_command_write_field_header(p, AS_FIELD_UDF_OP, 1);
		*p++ = 2;
		p = as_command_write_field_string(p, AS_FIELD_UDF_PACKAGE_NAME, scan->apply_each.module);
		p = as_command_write_field_string(p, AS_FIELD_UDF_FUNCTION, scan->apply_each.function);
		p = as_command_write_field_buffer(p, AS_FIELD_UDF_ARGLIST, argbuffer);
	}
    as_buffer_destroy(argbuffer);
	
	// Write predicate expressions.
	if (scan->predexp.size > 0) {
		p = as_command_write_field_header(p, AS_FIELD_PREDEXP, predexp_size);
		for (uint16_t ii = 0; ii < scan->predexp.size; ++ii) {
			as_predexp_base * bp = scan->predexp.entries[ii];
			p = (*bp->write_fn)(bp, p);
		}
	}
	
	if (scan->select.size > 0) {
		for (uint16_t i = 0; i < scan->select.size; i++) {
			p = as_command_write_bin_name(p, scan->select.entries[i]);
		}
	}

	return as_command_write_end(cmd, p);
}