Added more test cases for command line applications.
[m6w6/libmemcached] / libmemcached / server.c
1 /* LibMemcached
2 * Copyright (C) 2006-2009 Brian Aker
3 * All rights reserved.
4 *
5 * Use and distribution licensed under the BSD license. See
6 * the COPYING file in the parent directory for full text.
7 *
8 * Summary: String structure used for libmemcached.
9 *
10 */
11
12 /*
13 This is a partial implementation for fetching/creating memcached_server_st objects.
14 */
15 #include "common.h"
16
17 memcached_server_st *memcached_server_create(memcached_st *memc, memcached_server_st *ptr)
18 {
19 if (ptr == NULL)
20 {
21 ptr= (memcached_server_st *)memc->call_calloc(memc, 1, sizeof(memcached_server_st));
22
23 if (!ptr)
24 return NULL; /* MEMCACHED_MEMORY_ALLOCATION_FAILURE */
25
26 ptr->options.is_allocated= true;
27 }
28 else
29 {
30 memset(ptr, 0, sizeof(memcached_server_st));
31 }
32
33 ptr->root= memc;
34
35 return ptr;
36 }
37
38 memcached_server_st *memcached_server_create_with(memcached_st *memc, memcached_server_st *host,
39 const char *hostname, in_port_t port,
40 uint32_t weight, memcached_connection_t type)
41 {
42 host= memcached_server_create(memc, host);
43
44 if (host == NULL)
45 return NULL;
46
47 strncpy(host->hostname, hostname, MEMCACHED_MAX_HOST_LENGTH - 1);
48 host->root= memc ? memc : NULL;
49 host->port= port;
50 host->weight= weight;
51 host->fd= -1;
52 host->type= type;
53 host->read_ptr= host->read_buffer;
54 if (memc)
55 host->next_retry= memc->retry_timeout;
56 if (type == MEMCACHED_CONNECTION_UDP)
57 {
58 host->write_buffer_offset= UDP_DATAGRAM_HEADER_LENGTH;
59 memcached_io_init_udp_header(host, 0);
60 }
61
62 return host;
63 }
64
65 void memcached_server_free(memcached_server_st *ptr)
66 {
67 memcached_quit_server(ptr, 0);
68
69 if (ptr->cached_server_error)
70 free(ptr->cached_server_error);
71
72 if (ptr->address_info)
73 freeaddrinfo(ptr->address_info);
74
75
76 if (memcached_is_allocated(ptr))
77 {
78 ptr->root->call_free(ptr->root, ptr);
79 }
80 else
81 {
82 memset(ptr, 0, sizeof(memcached_server_st));
83 }
84 }
85
86 /*
87 If we do not have a valid object to clone from, we toss an error.
88 */
89 memcached_server_st *memcached_server_clone(memcached_server_st *clone, memcached_server_st *ptr)
90 {
91 memcached_server_st *rv= NULL;
92
93 /* We just do a normal create if ptr is missing */
94 if (ptr == NULL)
95 return NULL;
96
97 rv= memcached_server_create_with(ptr->root, clone,
98 ptr->hostname, ptr->port, ptr->weight,
99 ptr->type);
100 if (rv != NULL)
101 {
102 rv->cached_errno= ptr->cached_errno;
103 if (ptr->cached_server_error)
104 rv->cached_server_error= strdup(ptr->cached_server_error);
105 }
106
107 return rv;
108
109 }
110
111 memcached_return_t memcached_server_cursor(memcached_st *ptr,
112 memcached_server_fn *callback,
113 void *context,
114 uint32_t number_of_callbacks)
115 {
116 uint32_t y;
117
118 for (y= 0; y < memcached_server_count(ptr); y++)
119 {
120 uint32_t x;
121 memcached_server_instance_st *instance=
122 memcached_server_instance_fetch(ptr, y);
123
124 for (x= 0; x < number_of_callbacks; x++)
125 {
126 unsigned int iferror;
127
128 iferror= (*callback[x])(ptr, instance, context);
129
130 if (iferror)
131 continue;
132 }
133 }
134
135 return MEMCACHED_SUCCESS;
136 }
137
138 memcached_server_st *memcached_server_by_key(memcached_st *ptr, const char *key, size_t key_length, memcached_return_t *error)
139 {
140 uint32_t server_key;
141 memcached_server_instance_st *instance;
142
143 *error= memcached_validate_key_length(key_length,
144 ptr->flags.binary_protocol);
145 unlikely (*error != MEMCACHED_SUCCESS)
146 return NULL;
147
148 unlikely (memcached_server_count(ptr) == 0)
149 {
150 *error= MEMCACHED_NO_SERVERS;
151 return NULL;
152 }
153
154 if (ptr->flags.verify_key && (memcached_key_test((const char **)&key, &key_length, 1) == MEMCACHED_BAD_KEY_PROVIDED))
155 {
156 *error= MEMCACHED_BAD_KEY_PROVIDED;
157 return NULL;
158 }
159
160 server_key= memcached_generate_hash(ptr, key, key_length);
161 instance= memcached_server_instance_fetch(ptr, server_key);
162
163 return memcached_server_clone(NULL, instance);
164
165 }
166
167 const char *memcached_server_error(memcached_server_st *ptr)
168 {
169 return ptr
170 ? ptr->cached_server_error
171 : NULL;
172 }
173
174 void memcached_server_error_reset(memcached_server_st *ptr)
175 {
176 ptr->cached_server_error[0]= 0;
177 }
178
179 memcached_server_st *memcached_server_get_last_disconnect(memcached_st *ptr)
180 {
181 return ptr->last_disconnected_server;
182 }
183
184 uint32_t memcached_server_list_count(memcached_server_st *ptr)
185 {
186 return (ptr == NULL)
187 ? 0
188 : memcached_servers_count(ptr);
189 }
190
191 void memcached_server_list_free(memcached_server_st *ptr)
192 {
193 server_list_free(NULL, ptr);
194 }