Skip to content

Commit

Permalink
add get/read/exist? methods to Memcached::Rails
Browse files Browse the repository at this point in the history
  • Loading branch information
flyerhzm committed Aug 16, 2012
1 parent 944079f commit 7b33469
Show file tree
Hide file tree
Showing 4 changed files with 159 additions and 51 deletions.
36 changes: 36 additions & 0 deletions spec/rails_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,41 @@
it "should be active" do
@memcached.should be_active
end

context "get" do
it "should get value" do
@memcached.set "key", "value"
@memcached.get("key").should == "value"
end

it "should get nil if key is missing" do
@memcached.delete "key" rescue nil
@memcached.get("key").should be_nil
end
end

context "read" do
it "should get value" do
@memcached.set "key", "value"
@memcached.get("key").should == "value"
end

it "should get nil if key is missing" do
@memcached.delete "key" rescue nil
@memcached.get("key").should be_nil
end
end

context "exist?" do
it "should return true if key exists" do
@memcached.set "key", "value"
@memcached.exist?("key").should be_true
end

it "should return false if key is missing" do
@memcached.delete "key" rescue nil
@memcached.exist?("key").should be_false
end
end
end
end
100 changes: 56 additions & 44 deletions src/main/java/com/openfeint/memcached/Memcached.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,12 @@ public Memcached(final Ruby ruby, RubyClass rubyClass) {

@JRubyMethod(name = "initialize", optional = 2)
public IRubyObject initialize(ThreadContext context, IRubyObject[] args) {
Ruby ruby = context.getRuntime();
RubyHash options;
if (args.length > 1) {
options = args[1].convertToHash();
} else {
options = new RubyHash(getRuntime());
options = new RubyHash(ruby);
}
List<String> servers = new ArrayList<String>();
if (args.length > 0) {
Expand All @@ -70,82 +71,87 @@ public IRubyObject initialize(ThreadContext context, IRubyObject[] args) {

@JRubyMethod
public IRubyObject servers(ThreadContext context) {
Ruby ruby = context.getRuntime();
List<IRubyObject> addresses = new ArrayList<IRubyObject>();
for (SocketAddress address : client.getAvailableServers()) {
String addressStr = address.toString();
if (addressStr.indexOf("/") == 0) {
addressStr = addressStr.replace("/", "");
}
addresses.add(getRuntime().newString(addressStr));
addresses.add(ruby.newString(addressStr));
}
return getRuntime().newArray(addresses);
return ruby.newArray(addresses);
}

@JRubyMethod(name = "add", required = 2, optional = 3)
public IRubyObject add(ThreadContext context, IRubyObject[] args) {
Ruby ruby = context.getRuntime();
String key = getFullKey(args[0].toString());
IRubyObject value = args[1];
int timeout = getTimeout(args);
try {
boolean result = client.add(key, timeout, value, transcoder).get();
if (result == false) {
throw Error.newNotStored(getRuntime(), "not stored");
throw Error.newNotStored(ruby, "not stored");
}
return context.nil;
} catch (ExecutionException ee) {
throw context.runtime.newRuntimeError(ee.getLocalizedMessage());
throw ruby.newRuntimeError(ee.getLocalizedMessage());
} catch (InterruptedException ie) {
throw context.runtime.newThreadError(ie.getLocalizedMessage());
throw ruby.newThreadError(ie.getLocalizedMessage());
}
}

@JRubyMethod(name = "replace", required = 2, optional = 3)
public IRubyObject replace(ThreadContext context, IRubyObject [] args) {
Ruby ruby = context.getRuntime();
String key = getFullKey(args[0].toString());
IRubyObject value = args[1];
int timeout = getTimeout(args);
try {
boolean result = client.replace(key, timeout, value, transcoder).get();
if (result == false) {
throw Error.newNotStored(getRuntime(), "not stored");
throw Error.newNotStored(ruby, "not stored");
}
return context.nil;
} catch (ExecutionException ee) {
throw context.runtime.newRuntimeError(ee.getLocalizedMessage());
throw ruby.newRuntimeError(ee.getLocalizedMessage());
} catch (InterruptedException ie) {
throw context.runtime.newThreadError(ie.getLocalizedMessage());
throw ruby.newThreadError(ie.getLocalizedMessage());
}
}

@JRubyMethod(name = "set", required = 2, optional = 3)
public IRubyObject set(ThreadContext context, IRubyObject[] args) {
Ruby ruby = context.getRuntime();
String key = getFullKey(args[0].toString());
IRubyObject value = args[1];
int timeout = getTimeout(args);
try {
boolean result = client.set(key, timeout, value, transcoder).get();
if (result == false) {
throw Error.newNotStored(getRuntime(), "not stored");
throw Error.newNotStored(ruby, "not stored");
}
return context.nil;
} catch (ExecutionException ee) {
throw context.runtime.newRuntimeError(ee.getLocalizedMessage());
throw ruby.newRuntimeError(ee.getLocalizedMessage());
} catch (InterruptedException ie) {
throw context.runtime.newThreadError(ie.getLocalizedMessage());
throw ruby.newThreadError(ie.getLocalizedMessage());
}
}

@JRubyMethod(name = "get", required = 1, optional = 1)
public IRubyObject get(ThreadContext context, IRubyObject[] args) {
Ruby ruby = context.getRuntime();
IRubyObject keys = args[0];
if (keys instanceof RubyString) {
IRubyObject value = client.get(getFullKey(keys.toString()), transcoder);
if (value == null) {
throw Error.newNotFound(getRuntime(), "not found");
throw Error.newNotFound(ruby, "not found");
}
return value;
} else if (keys instanceof RubyArray) {
RubyHash results = RubyHash.newHash(getRuntime());
RubyHash results = RubyHash.newHash(ruby);

Map<String, IRubyObject> bulkResults = client.getBulk(getFullKeys(keys.convertToArray()), transcoder);
for (String key : (List<String>) keys.convertToArray()) {
Expand All @@ -160,58 +166,63 @@ public IRubyObject get(ThreadContext context, IRubyObject[] args) {

@JRubyMethod(name = "incr", required = 1, optional = 2)
public IRubyObject incr(ThreadContext context, IRubyObject[] args) {
Ruby ruby = context.getRuntime();
String key = getFullKey(args[0].toString());
int by = getIncrDecrBy(args);
int timeout = getTimeout(args);
long result = client.incr(key, by, 1, timeout);
return getRuntime().newFixnum(result);
return ruby.newFixnum(result);
}

@JRubyMethod(name = "decr", required = 1, optional = 2)
public IRubyObject decr(ThreadContext context, IRubyObject[] args) {
Ruby ruby = context.getRuntime();
String key = getFullKey(args[0].toString());
int by = getIncrDecrBy(args);
int timeout = getTimeout(args);
long result = client.decr(key, by, 0, timeout);
return getRuntime().newFixnum(result);
return ruby.newFixnum(result);
}

@JRubyMethod
public IRubyObject delete(ThreadContext context, IRubyObject key) {
Ruby ruby = context.getRuntime();
try {
boolean result = client.delete(getFullKey(key.toString())).get();
if (result == false) {
throw Error.newNotFound(getRuntime(), "not found");
throw Error.newNotFound(ruby, "not found");
}
return context.nil;
} catch (ExecutionException ee) {
throw context.runtime.newRuntimeError(ee.getLocalizedMessage());
throw ruby.newRuntimeError(ee.getLocalizedMessage());
} catch (InterruptedException ie) {
throw context.runtime.newThreadError(ie.getLocalizedMessage());
throw ruby.newThreadError(ie.getLocalizedMessage());
}
}

@JRubyMethod
public IRubyObject flush(ThreadContext context) {
Ruby ruby = context.getRuntime();
try {
client.flush().get();
return context.nil;
} catch (ExecutionException ee) {
throw context.runtime.newRuntimeError(ee.getLocalizedMessage());
throw ruby.newRuntimeError(ee.getLocalizedMessage());
} catch (InterruptedException ie) {
throw context.runtime.newThreadError(ie.getLocalizedMessage());
throw ruby.newThreadError(ie.getLocalizedMessage());
}
}

@JRubyMethod
public IRubyObject stats(ThreadContext context) {
RubyHash results = RubyHash.newHash(getRuntime());
Ruby ruby = context.getRuntime();
RubyHash results = RubyHash.newHash(ruby);
for(Map.Entry<SocketAddress, Map<String, String>> entry : client.getStats().entrySet()) {
RubyHash serverHash = RubyHash.newHash(getRuntime());
RubyHash serverHash = RubyHash.newHash(ruby);
for(Map.Entry<String, String> server : entry.getValue().entrySet()) {
serverHash.op_aset(context, getRuntime().newString(server.getKey()), getRuntime().newString(server.getValue()));
serverHash.op_aset(context, ruby.newString(server.getKey()), ruby.newString(server.getValue()));
}
results.op_aset(context, getRuntime().newString(entry.getKey().toString()), serverHash);
results.op_aset(context, ruby.newString(entry.getKey().toString()), serverHash);
}
return results;
}
Expand All @@ -224,6 +235,7 @@ public IRubyObject shutdown(ThreadContext context) {
}

protected IRubyObject init(ThreadContext context, List<String> servers, RubyHash options) {
Ruby ruby = context.getRuntime();
List<InetSocketAddress> addresses = AddrUtil.getAddresses(servers);
try {
ConnectionFactoryBuilder builder = new ConnectionFactoryBuilder();
Expand All @@ -234,26 +246,26 @@ protected IRubyObject init(ThreadContext context, List<String> servers, RubyHash
String transcoderValue = null;
if (!options.isEmpty()) {
RubyHash opts = options.convertToHash();
if (opts.containsKey(getRuntime().newSymbol("distribution"))) {
distributionValue = opts.get(getRuntime().newSymbol("distribution")).toString();
if (opts.containsKey(ruby.newSymbol("distribution"))) {
distributionValue = opts.get(ruby.newSymbol("distribution")).toString();
}
if (opts.containsKey(getRuntime().newSymbol("hash"))) {
hashValue = opts.get(getRuntime().newSymbol("hash")).toString();
if (opts.containsKey(ruby.newSymbol("hash"))) {
hashValue = opts.get(ruby.newSymbol("hash")).toString();
}
if (opts.containsKey(getRuntime().newSymbol("binary_protocol"))) {
binaryValue = opts.get(getRuntime().newSymbol("binary_protocol")).toString();
if (opts.containsKey(ruby.newSymbol("binary_protocol"))) {
binaryValue = opts.get(ruby.newSymbol("binary_protocol")).toString();
}
if (opts.containsKey(getRuntime().newSymbol("default_ttl"))) {
ttl = Integer.parseInt(opts.get(getRuntime().newSymbol("default_ttl")).toString());
if (opts.containsKey(ruby.newSymbol("default_ttl"))) {
ttl = Integer.parseInt(opts.get(ruby.newSymbol("default_ttl")).toString());
}
if (opts.containsKey(getRuntime().newSymbol("namespace"))) {
prefixKey = opts.get(getRuntime().newSymbol("namespace")).toString();
if (opts.containsKey(ruby.newSymbol("namespace"))) {
prefixKey = opts.get(ruby.newSymbol("namespace")).toString();
}
if (opts.containsKey(getRuntime().newSymbol("prefix_key"))) {
prefixKey = opts.get(getRuntime().newSymbol("prefix_key")).toString();
if (opts.containsKey(ruby.newSymbol("prefix_key"))) {
prefixKey = opts.get(ruby.newSymbol("prefix_key")).toString();
}
if (opts.containsKey(getRuntime().newSymbol("transcoder"))) {
transcoderValue = opts.get(getRuntime().newSymbol("transcoder")).toString();
if (opts.containsKey(ruby.newSymbol("transcoder"))) {
transcoderValue = opts.get(ruby.newSymbol("transcoder")).toString();
}
}

Expand All @@ -262,7 +274,7 @@ protected IRubyObject init(ThreadContext context, List<String> servers, RubyHash
} else if ("ketama".equals(distributionValue) || "consistent_ketama".equals(distributionValue)) {
builder.setLocatorType(Locator.CONSISTENT);
} else {
throw Error.newNotSupport(getRuntime(), "distribution not support");
throw Error.newNotSupport(ruby, "distribution not support");
}
if ("native".equals(hashValue)) {
builder.setHashAlg(DefaultHashAlgorithm.NATIVE_HASH);
Expand All @@ -279,7 +291,7 @@ protected IRubyObject init(ThreadContext context, List<String> servers, RubyHash
} else if ("ketama".equals(hashValue)) {
builder.setHashAlg(DefaultHashAlgorithm.KETAMA_HASH);
} else {
throw Error.newNotSupport(getRuntime(), "hash not support");
throw Error.newNotSupport(ruby, "hash not support");
}

if ("true".equals(binaryValue)) {
Expand All @@ -289,12 +301,12 @@ protected IRubyObject init(ThreadContext context, List<String> servers, RubyHash
client = new MemcachedClient(builder.build(), addresses);

if ("marshal_zlib".equals(transcoderValue)) {
transcoder = new MarshalZlibTranscoder(getRuntime());
transcoder = new MarshalZlibTranscoder(ruby);
} else {
transcoder = new MarshalTranscoder(getRuntime());
transcoder = new MarshalTranscoder(ruby);
}
} catch (IOException ioe) {
throw context.runtime.newIOErrorFromException(ioe);
throw ruby.newIOErrorFromException(ioe);
}

return context.nil;
Expand Down
Loading

0 comments on commit 7b33469

Please sign in to comment.