| 1 | #include <libmemcached/memcached.h> |
|---|
| 2 | #include <v8.h> |
|---|
| 3 | #include <cstring> |
|---|
| 4 | |
|---|
| 5 | using namespace v8; |
|---|
| 6 | |
|---|
| 7 | inline memcached_st * _memc(const v8::Arguments& args) { |
|---|
| 8 | v8::Local<v8::Value> field = args.This()->GetInternalField(0); |
|---|
| 9 | return reinterpret_cast<memcached_st *>(v8::Handle<v8::External>::Cast(field)->Value()); |
|---|
| 10 | } |
|---|
| 11 | |
|---|
| 12 | v8::Handle<v8::Value> _new(const v8::Arguments& args) { |
|---|
| 13 | v8::HandleScope handle_scope; |
|---|
| 14 | |
|---|
| 15 | memcached_st *memc = memcached_create(NULL);; |
|---|
| 16 | args.This()->SetInternalField(0, v8::External::New((void*)memc)); |
|---|
| 17 | return args.This(); |
|---|
| 18 | } |
|---|
| 19 | |
|---|
| 20 | v8::Handle<v8::Value> _free(const v8::Arguments& args) { |
|---|
| 21 | v8::HandleScope handle_scope; |
|---|
| 22 | memcached_st *memc = _memc(args); |
|---|
| 23 | memcached_free(memc); |
|---|
| 24 | } |
|---|
| 25 | |
|---|
| 26 | v8::Handle<v8::Value> _server_add(const v8::Arguments& args) { |
|---|
| 27 | if (args.Length() != 2) { |
|---|
| 28 | return v8::ThrowException(v8::String::New("Exception: missing args: server_add(host, port)")); |
|---|
| 29 | } |
|---|
| 30 | |
|---|
| 31 | HandleScope handle_scope; |
|---|
| 32 | memcached_return rc; |
|---|
| 33 | memcached_st *memc = _memc(args); |
|---|
| 34 | |
|---|
| 35 | String::AsciiValue host(args[0]); |
|---|
| 36 | |
|---|
| 37 | rc = memcached_server_add(memc, *host, args[1]->Int32Value()); |
|---|
| 38 | if (rc != MEMCACHED_SUCCESS) { |
|---|
| 39 | return ThrowException(String::New(memcached_strerror(memc, rc))); |
|---|
| 40 | } |
|---|
| 41 | return Undefined(); |
|---|
| 42 | } |
|---|
| 43 | |
|---|
| 44 | v8::Handle<v8::Value> _get(const v8::Arguments& args) { |
|---|
| 45 | if (args.Length() != 1) { |
|---|
| 46 | return v8::ThrowException(v8::String::New("Exception: missing args: get(key)")); |
|---|
| 47 | } |
|---|
| 48 | |
|---|
| 49 | HandleScope handle_scope; |
|---|
| 50 | memcached_return rc; |
|---|
| 51 | memcached_st *memc = _memc(args); |
|---|
| 52 | uint32_t flags; |
|---|
| 53 | size_t value_length; |
|---|
| 54 | |
|---|
| 55 | String::AsciiValue key(args[0]); |
|---|
| 56 | char * value = memcached_get(memc, *key, strlen(*key), |
|---|
| 57 | &value_length, &flags, &rc); |
|---|
| 58 | if (rc == MEMCACHED_NOTFOUND) { |
|---|
| 59 | return Undefined(); |
|---|
| 60 | } else if (rc == MEMCACHED_SUCCESS) { |
|---|
| 61 | Handle<Object> res = Object::New(); |
|---|
| 62 | res->Set(String::New("value"), String::New(value, value_length)); |
|---|
| 63 | res->Set(String::New("flags"), Integer::New(flags)); |
|---|
| 64 | free(value); |
|---|
| 65 | return res; |
|---|
| 66 | } else { |
|---|
| 67 | return ThrowException(String::New(memcached_strerror(memc, rc))); |
|---|
| 68 | } |
|---|
| 69 | } |
|---|
| 70 | |
|---|
| 71 | v8::Handle<v8::Value> _set(const v8::Arguments& args) { |
|---|
| 72 | if (args.Length() != 4) { |
|---|
| 73 | return v8::ThrowException(v8::String::New("Exception: missing args: set(key, val, expiration, flags)")); |
|---|
| 74 | } |
|---|
| 75 | |
|---|
| 76 | HandleScope handle_scope; |
|---|
| 77 | memcached_st *memc = _memc(args); |
|---|
| 78 | |
|---|
| 79 | String::AsciiValue key(args[0]); |
|---|
| 80 | String::AsciiValue val(args[1]); |
|---|
| 81 | time_t expiration = args[2]->Uint32Value(); |
|---|
| 82 | uint32_t flags = args[3]->Uint32Value(); |
|---|
| 83 | |
|---|
| 84 | memcached_return rc = memcached_set( |
|---|
| 85 | memc, |
|---|
| 86 | *key, args[0]->ToString()->Length(), |
|---|
| 87 | *val, args[1]->ToString()->Length(), |
|---|
| 88 | expiration, |
|---|
| 89 | flags |
|---|
| 90 | ); |
|---|
| 91 | if (rc != MEMCACHED_SUCCESS) { |
|---|
| 92 | return ThrowException(String::New(memcached_strerror(memc, rc))); |
|---|
| 93 | } else { |
|---|
| 94 | return Undefined(); |
|---|
| 95 | } |
|---|
| 96 | } |
|---|
| 97 | |
|---|
| 98 | void setup_memcached(v8::Handle<v8::ObjectTemplate> target) { |
|---|
| 99 | HandleScope scope; |
|---|
| 100 | |
|---|
| 101 | Handle<FunctionTemplate> ft = FunctionTemplate::New(_new); |
|---|
| 102 | Handle<ObjectTemplate> ot = ft->InstanceTemplate(); |
|---|
| 103 | |
|---|
| 104 | ot->Set(String::New("server_add"), FunctionTemplate::New(_server_add)); |
|---|
| 105 | ot->Set(String::New("get"), FunctionTemplate::New(_get)); |
|---|
| 106 | ot->Set(String::New("set"), FunctionTemplate::New(_set)); |
|---|
| 107 | ot->Set(String::New("free"), FunctionTemplate::New(_free)); |
|---|
| 108 | |
|---|
| 109 | ot->SetInternalFieldCount(1); |
|---|
| 110 | target->Set( |
|---|
| 111 | String::New("Memcached"), |
|---|
| 112 | ft, |
|---|
| 113 | PropertyAttribute(ReadOnly | DontDelete) |
|---|
| 114 | ); |
|---|
| 115 | } |
|---|
| 116 | |
|---|