Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

121 lines (109 sloc) 4.709 kB
/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
* Copyright 2010, 2011 Couchbase, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "internal.h"
/**
* Spool a store request
*
* @author Trond Norbye
* @todo add documentation
* @todo fix the expiration so that it works relative/absolute etc..
* @todo we might want to wait to write the data to the sockets if the
* user want to run a batch of store requests?
*/
LIBCOUCHBASE_API
lcb_error_t lcb_store(lcb_t instance,
const void *command_cookie,
lcb_size_t num,
const lcb_store_cmd_t *const *items)
{
size_t ii;
/* we need a vbucket config before we can start getting data.. */
if (instance->vbucket_config == NULL) {
return lcb_synchandler_return(instance, LCB_ETMPFAIL);
}
for (ii = 0; ii < num; ++ii) {
lcb_server_t *server;
protocol_binary_request_set req;
lcb_size_t headersize;
lcb_size_t bodylen;
int vb, idx;
lcb_storage_t operation = items[ii]->v.v0.operation;
const void *key = items[ii]->v.v0.key;
lcb_size_t nkey = items[ii]->v.v0.nkey;
lcb_cas_t cas = items[ii]->v.v0.cas;
lcb_uint32_t flags = items[ii]->v.v0.flags;
lcb_time_t exp = items[ii]->v.v0.exptime;
const void *bytes = items[ii]->v.v0.bytes;
lcb_size_t nbytes = items[ii]->v.v0.nbytes;
(void)vbucket_map(instance->vbucket_config, key, nkey, &vb, &idx);
if (idx < 0 || idx > (int)instance->nservers) {
/*
** the config says that there is no server yet at that
** position (-1)
*/
return lcb_synchandler_return(instance, LCB_NETWORK_ERROR);
}
server = instance->servers + idx;
memset(&req, 0, sizeof(req));
req.message.header.request.magic = PROTOCOL_BINARY_REQ;
req.message.header.request.keylen = ntohs((lcb_uint16_t)nkey);
req.message.header.request.extlen = 8;
req.message.header.request.datatype = PROTOCOL_BINARY_RAW_BYTES;
req.message.header.request.vbucket = ntohs((lcb_uint16_t)vb);
req.message.header.request.opaque = ++instance->seqno;
req.message.header.request.cas = cas;
req.message.body.flags = htonl(flags);
req.message.body.expiration = htonl((lcb_uint32_t)exp);
headersize = sizeof(req.bytes);
switch (operation) {
case LCB_ADD:
req.message.header.request.opcode = PROTOCOL_BINARY_CMD_ADD;
break;
case LCB_REPLACE:
req.message.header.request.opcode = PROTOCOL_BINARY_CMD_REPLACE;
break;
case LCB_SET:
req.message.header.request.opcode = PROTOCOL_BINARY_CMD_SET;
break;
case LCB_APPEND:
req.message.header.request.opcode = PROTOCOL_BINARY_CMD_APPEND;
req.message.header.request.extlen = 0;
headersize -= 8;
break;
case LCB_PREPEND:
req.message.header.request.opcode = PROTOCOL_BINARY_CMD_PREPEND;
req.message.header.request.extlen = 0;
headersize -= 8;
break;
default:
/* We were given an unknown storage operation. */
return lcb_synchandler_return(instance,
lcb_error_handler(instance, LCB_EINVAL,
"Invalid value passed as storage operation"));
}
/* Make it known that this was a success. */
lcb_error_handler(instance, LCB_SUCCESS, NULL);
bodylen = nkey + nbytes + req.message.header.request.extlen;
req.message.header.request.bodylen = htonl((lcb_uint32_t)bodylen);
lcb_server_start_packet(server, command_cookie, &req, headersize);
lcb_server_write_packet(server, key, nkey);
lcb_server_write_packet(server, bytes, nbytes);
lcb_server_end_packet(server);
lcb_server_send_packets(server);
}
return lcb_synchandler_return(instance, LCB_SUCCESS);
}
Jump to Line
Something went wrong with that request. Please try again.