root/lang/cplusplus/llv8call/trunk/ext/libmemcached/libmemcached.cc @ 19835

Revision 19835, 10.1 kB (checked in by tokuhirom, 6 years ago)

change ext/ directory structure.

Line 
1#include <libmemcached/memcached.h>
2#include <v8.h>
3#include <cstring>
4#include <string>
5#include "v8ext.h"
6#include "llv8-util.h"
7
8using namespace v8;
9
10static inline memcached_st * _memc(const Arguments& args) {
11    return handle<memcached_st>(args, 0);
12}
13
14inline static Handle<Value> throw_exception(memcached_st * memc, memcached_return rc, const char*funcname) {
15    std::string str("Memcached Error(");
16    str += funcname;
17    str += "): ";
18    str += memcached_strerror(memc, rc);
19    return ThrowException(String::New(str.c_str()));
20}
21
22static Handle<Value> _new(const Arguments& args) {
23    HandleScope handle_scope;
24
25    memcached_st *memc = memcached_create(NULL);;
26    args.This()->SetInternalField(0, External::New((void*)memc));
27    return args.This();
28}
29
30static Handle<Value> _server_add(const Arguments& args) {
31    if (args.Length() != 2) {
32        return ThrowException(String::New("Exception: missing args: server_add(host, port)"));
33    }
34
35    HandleScope handle_scope;
36    memcached_return rc;
37    memcached_st *memc = _memc(args);
38
39    String::AsciiValue host(args[0]);
40
41    rc = memcached_server_add(memc, *host, args[1]->Int32Value());
42    if (rc != MEMCACHED_SUCCESS) {
43        return throw_exception(memc, rc, "server_add");
44    }
45    return Undefined();
46}
47
48static Handle<Value> _behavior_set(const Arguments& args) {
49    if (args.Length() != 2) {
50        return ThrowException(String::New("Exception: missing args: BehaviorSet(flag, data)"));
51    }
52    if (args[0]->IsUndefined()) {
53        return ThrowException(String::New("Exception: invalid args: args[0] should not be undefined."));
54    }
55
56    HandleScope handle_scope;
57    memcached_return rc;
58    memcached_st *memc = _memc(args);
59
60    rc = memcached_behavior_set(memc, memcached_behavior(args[0]->Int32Value()), args[1]->Int32Value());
61    if (rc != MEMCACHED_SUCCESS) {
62        return throw_exception(memc, rc, "behavior_set");
63    }
64    return Undefined();
65}
66
67static Handle<Value> _behavior_get(const Arguments& args) {
68    if (args.Length() != 1) {
69        return ThrowException(String::New("Exception: missing args: BehaviorGet(flag)"));
70    }
71
72    HandleScope handle_scope;
73    memcached_return rc;
74    memcached_st *memc = _memc(args);
75
76    uint64_t data = (uint64_t)(
77        memcached_behavior_get(memc, memcached_behavior(args[0]->Int32Value()))
78    );
79    return Integer::New(data);
80}
81
82static Handle<Value> _get(const Arguments& args) {
83    if (args.Length() != 1) {
84        return ThrowException(String::New("Exception: missing args: get(key)"));
85    }
86
87    HandleScope handle_scope;
88    memcached_return rc;
89    memcached_st *memc = _memc(args);
90    uint32_t flags;
91    size_t value_length;
92
93    String::AsciiValue key(args[0]);
94    char * value = memcached_get(memc, *key, strlen(*key),
95                            &value_length, &flags, &rc);
96    if (rc == MEMCACHED_NOTFOUND) {
97        return Undefined();
98    } else if (rc == MEMCACHED_SUCCESS) {
99        Handle<Object> res = Object::New();
100        res->Set(String::New("value"), String::New(value, value_length));
101        res->Set(String::New("flags"), Integer::New(flags));
102        free(value);
103        return res;
104    } else {
105        return throw_exception(memc, rc, "get");
106    }
107}
108
109static Handle<Value> _set(const Arguments& args) {
110    if (args.Length() != 4) {
111        return ThrowException(String::New("Exception: missing args: set(key, val, expiration, flags)"));
112    }
113
114    HandleScope handle_scope;
115    memcached_st *memc = _memc(args);
116
117    String::AsciiValue key(args[0]);
118    String::AsciiValue val(args[1]);
119    time_t expiration = args[2]->Uint32Value();
120    uint32_t flags    = args[3]->Uint32Value();
121
122    memcached_return rc = memcached_set(
123        memc,
124        *key, args[0]->ToString()->Length(),
125        *val, args[1]->ToString()->Length(),
126        expiration,
127        flags
128    );
129    if (rc != MEMCACHED_SUCCESS && rc != MEMCACHED_BUFFERED) {
130        return throw_exception(memc, rc, "set");
131    } else {
132        return Undefined();
133    }
134}
135
136static Handle<Value> _del(const Arguments& args) {
137    if (args.Length() != 1) {
138        return ThrowException(String::New("Exception: missing args: del(key)"));
139    }
140
141    HandleScope handle_scope;
142    memcached_st *memc = _memc(args);
143
144    String::AsciiValue key(args[0]);
145    time_t expiration = args[1]->Uint32Value();
146    memcached_return rc = memcached_delete(
147        memc,
148        *key, args[0]->ToString()->Length(),
149        expiration
150    );
151    if (rc == MEMCACHED_SUCCESS) {
152        return Undefined();
153    } else {
154        return throw_exception(memc, rc, "del");
155    }
156}
157
158static Handle<Value> _increment(const Arguments& args) {
159    if (args.Length() != 2) {
160        return ThrowException(String::New("Exception: missing args: incr(key, offset)"));
161    }
162
163    HandleScope handle_scope;
164    memcached_st *memc = _memc(args);
165
166    String::AsciiValue key(args[0]);
167    uint32_t offset = args[1]->Uint32Value();
168    uint64_t buf;
169
170    memcached_return rc = memcached_increment(
171        memc,
172        *key, args[0]->ToString()->Length(),
173        offset,
174        &buf
175    );
176    if (rc != MEMCACHED_SUCCESS) {
177        return throw_exception(memc, rc, "increment");
178    } else {
179        return Integer::New(buf);
180    }
181}
182
183static Handle<Value> _decrement(const Arguments& args) {
184    if (args.Length() != 2) {
185        return ThrowException(String::New("Exception: missing args: decrement(key, offset)"));
186    }
187
188    HandleScope handle_scope;
189    memcached_st *memc = _memc(args);
190
191    String::AsciiValue key(args[0]);
192    uint32_t offset = args[1]->Uint32Value();
193    uint64_t buf;
194
195    memcached_return rc = memcached_decrement(
196        memc,
197        *key, args[0]->ToString()->Length(),
198        offset,
199        &buf
200    );
201    if (rc != MEMCACHED_SUCCESS) {
202        return throw_exception(memc, rc, "decrement");
203    } else {
204        return Integer::New(buf);
205    }
206}
207
208static Handle<Value> _lib_version(const Arguments& args) {
209    HandleScope handle_scope;
210    return String::New(memcached_lib_version());
211}
212
213static Handle<Value> _ServerCount(const Arguments& args) {
214    HandleScope handle_scope;
215    memcached_st* memc = _memc(args);
216    unsigned int i = memcached_server_count(memc);
217    return Int32::New(i);
218}
219
220static Handle<Value> _Stat(const Arguments& args) {
221    HandleScope handle_scope;
222    memcached_st* memc = _memc(args);
223    memcached_return rc;
224    memcached_stat_st * stat = memcached_stat(memc, NULL, &rc);
225    if (rc != MEMCACHED_SUCCESS && rc != MEMCACHED_SOME_ERRORS) {
226        return throw_exception(memc, rc, "stat");
227    }
228    memcached_server_st * server_list = memcached_server_list(memc);
229    Handle<Array> res = Array::New();
230    for (int i=0; i<memcached_server_count(memc); i++) {
231        char **list = memcached_stat_get_keys(memc, &stat[i], &rc);
232        Handle<Object> row = Object::New();
233        for (char **ptr = list; *ptr; ptr++) {
234            memcached_return rc;
235            char *value= memcached_stat_get_value(memc, &stat[i], *ptr, &rc);
236            row->Set(String::New(*ptr), String::New(value));
237            free(value);
238        }
239        res->Set(Int32::New(i), row);
240        free(list);
241    }
242    free(stat);
243    return res;
244}
245
246static Handle<Value> _free(const Arguments& args) {
247    HandleScope handle_scope;
248    memcached_st* memc = _memc(args);
249    memcached_free(memc);
250    return Undefined();
251}
252
253extern "C" V8EXTINIT_FUNC
254void init_lib(Handle<Object>obj) {
255    HandleScope scope;
256
257    Handle<FunctionTemplate> ft = FunctionTemplate::New(_new);
258    ft->Set("LibVersion", String::New(memcached_lib_version()));
259    // generated by:
260    //    perl -ne 'print qq{ft->Set("$2", Int32::New($1));\n} if /(MEMCACHED_(BEHAVIOR.+)),/' /opt/local/include/libmemcached/memcached_constants.h
261    ft->Set("BEHAVIOR_NO_BLOCK", Int32::New(MEMCACHED_BEHAVIOR_NO_BLOCK));
262    ft->Set("BEHAVIOR_TCP_NODELAY", Int32::New(MEMCACHED_BEHAVIOR_TCP_NODELAY));
263    ft->Set("BEHAVIOR_HASH", Int32::New(MEMCACHED_BEHAVIOR_HASH));
264    ft->Set("BEHAVIOR_KETAMA", Int32::New(MEMCACHED_BEHAVIOR_KETAMA));
265    ft->Set("BEHAVIOR_SOCKET_SEND_SIZE", Int32::New(MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE));
266    ft->Set("BEHAVIOR_SOCKET_RECV_SIZE", Int32::New(MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE));
267    ft->Set("BEHAVIOR_CACHE_LOOKUPS", Int32::New(MEMCACHED_BEHAVIOR_CACHE_LOOKUPS));
268    ft->Set("BEHAVIOR_SUPPORT_CAS", Int32::New(MEMCACHED_BEHAVIOR_SUPPORT_CAS));
269    ft->Set("BEHAVIOR_POLL_TIMEOUT", Int32::New(MEMCACHED_BEHAVIOR_POLL_TIMEOUT));
270    ft->Set("BEHAVIOR_DISTRIBUTION", Int32::New(MEMCACHED_BEHAVIOR_DISTRIBUTION));
271    ft->Set("BEHAVIOR_BUFFER_REQUESTS", Int32::New(MEMCACHED_BEHAVIOR_BUFFER_REQUESTS));
272    ft->Set("BEHAVIOR_USER_DATA", Int32::New(MEMCACHED_BEHAVIOR_USER_DATA));
273    ft->Set("BEHAVIOR_SORT_HOSTS", Int32::New(MEMCACHED_BEHAVIOR_SORT_HOSTS));
274    ft->Set("BEHAVIOR_VERIFY_KEY", Int32::New(MEMCACHED_BEHAVIOR_VERIFY_KEY));
275    ft->Set("BEHAVIOR_CONNECT_TIMEOUT", Int32::New(MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT));
276    ft->Set("BEHAVIOR_RETRY_TIMEOUT", Int32::New(MEMCACHED_BEHAVIOR_RETRY_TIMEOUT));
277    ft->Set("BEHAVIOR_KETAMA_WEIGHTED", Int32::New(MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED));
278    ft->Set("BEHAVIOR_KETAMA_HASH", Int32::New(MEMCACHED_BEHAVIOR_KETAMA_HASH));
279    ft->Set("BEHAVIOR_BINARY_PROTOCOL", Int32::New(MEMCACHED_BEHAVIOR_BINARY_PROTOCOL));
280    ft->Set("BEHAVIOR_SND_TIMEOUT", Int32::New(MEMCACHED_BEHAVIOR_SND_TIMEOUT));
281    ft->Set("BEHAVIOR_RCV_TIMEOUT", Int32::New(MEMCACHED_BEHAVIOR_RCV_TIMEOUT));
282
283    Handle<ObjectTemplate>   ot = ft->InstanceTemplate();
284
285    ot->Set("ServerAdd",   FunctionTemplate::New(_server_add));
286    ot->Set("BehaviorSet", FunctionTemplate::New(_behavior_set));
287    ot->Set("BehaviorGet", FunctionTemplate::New(_behavior_get));
288    ot->Set("Get",         FunctionTemplate::New(_get));
289    ot->Set("Set",         FunctionTemplate::New(_set));
290    ot->Set("Del",         FunctionTemplate::New(_del));
291    ot->Set("Increment",   FunctionTemplate::New(_increment));
292    ot->Set("Decrement",   FunctionTemplate::New(_decrement));
293    ot->Set("Free",        FunctionTemplate::New(_free));
294    ot->Set("ServerCount", FunctionTemplate::New(_ServerCount));
295    ot->Set("Stat",        FunctionTemplate::New(_Stat));
296
297    ot->SetInternalFieldCount(1);
298    obj->Set(
299        String::New("Memcached"),
300        ft->GetFunction()
301    );
302}
303
Note: See TracBrowser for help on using the browser.