Coerce objects to strings for get and elsewhere. Closes #105.

This commit is contained in:
Evan Weaver 2013-06-11 00:11:18 -07:00
Родитель 0fcbcacca9
Коммит 19a23876e3
5 изменённых файлов: 1446 добавлений и 1277 удалений

Просмотреть файл

@ -46,6 +46,15 @@ Echoe.new("memcached") do |p|
"**/*.rbc"]
end
task :swig do
run("swig -DLIBMEMCACHED_WITH_SASL_SUPPORT -Iext/libmemcached-0.32 -ruby -autorename -o ext/rlibmemcached_wrap.c.in ext/rlibmemcached.i", "Running SWIG")
swig_patches = {
"#ifndef RUBY_INIT_STACK" => "#ifdef __NEVER__" # Patching SWIG output for JRuby.
}.map{|pair| "s/#{pair.join('/')}/"}.join(';')
# sed has different syntax for inplace switch in BSD and GNU version, so using intermediate file
run("sed '#{swig_patches}' ext/rlibmemcached_wrap.c.in > ext/rlibmemcached_wrap.c", "Apply patches to SWIG output")
end
task :exceptions do
$LOAD_PATH << "lib"
require 'memcached'
@ -116,3 +125,8 @@ task :benchmark_all do
with_vms("benchmark CLIENT=libm")
end
def run(cmd, reason)
puts reason
puts cmd
raise "'#{cmd}' failed" unless system(cmd)
end

Просмотреть файл

@ -33,17 +33,10 @@ if ENV['DEBUG']
$EXTRA_CONF = ""
end
def run(cmd, reason)
puts reason
puts cmd
raise "'#{cmd}' failed" unless system(cmd)
end
def check_libmemcached
return if ENV["EXTERNAL_LIB"]
$includes = " -I#{HERE}/include"
$defines = " -DLIBMEMCACHED_WITH_SASL_SUPPORT"
$libraries = " -L#{HERE}/lib"
$CFLAGS = "#{$includes} #{$libraries} #{$CFLAGS}"
$LDFLAGS = "-lsasl2 -lm #{$libraries} #{$LDFLAGS}"
@ -71,21 +64,14 @@ def check_libmemcached
$LIBS << " -lmemcached_gem -lsasl2"
end
check_libmemcached
if ENV['SWIG']
puts "WARNING: Swig 2.0.2 not found. Other versions may not work." if (`swig -version`!~ /2.0.2/)
run("swig #{$defines} #{$includes} -ruby -autorename -o rlibmemcached_wrap.c.in rlibmemcached.i", "Running SWIG.")
swig_patches = {
"STR2CSTR" => "StringValuePtr", # Patching SWIG output for Ruby 1.9.
"\"swig_runtime_data\"" => "\"SwigRuntimeData\"", # Patching SWIG output for Ruby 1.9.
"#ifndef RUBY_INIT_STACK" => "#ifdef __NEVER__", # Patching SWIG output for JRuby.
}.map{|pair| "s/#{pair.join('/')}/"}.join(';')
# sed has different syntax for inplace switch in BSD and GNU version, so using intermediate file
run("sed '#{swig_patches}' rlibmemcached_wrap.c.in > rlibmemcached_wrap.c", "Apply patches to SWIG output")
def run(cmd, reason)
puts reason
puts cmd
raise "'#{cmd}' failed" unless system(cmd)
end
check_libmemcached
$CFLAGS << " -Os"
create_makefile 'rlibmemcached'
run("mv Makefile Makefile.in", "Copy Makefile")

Просмотреть файл

@ -2,6 +2,7 @@
%{
#include <libmemcached/visibility.h>
#include <libmemcached/memcached.h>
#include <libmemcached/memcached_exist.h>
%}
%warnfilter(SWIGWARN_RUBY_WRONG_NAME) memcached_st;
@ -40,14 +41,15 @@
// Array of strings map for multiget
%typemap(in) (const char **keys, size_t *key_length, size_t number_of_keys) {
unsigned int i;
VALUE str;
Check_Type($input, T_ARRAY);
$3 = (unsigned int) RARRAY_LEN($input);
$2 = (size_t *) malloc(($3+1)*sizeof(size_t));
$1 = (char **) malloc(($3+1)*sizeof(char *));
for(i = 0; i < $3; i ++) {
Check_Type(RARRAY_PTR($input)[i], T_STRING);
$2[i] = RSTRING_LEN(RARRAY_PTR($input)[i]);
$1[i] = StringValuePtr(RARRAY_PTR($input)[i]);
str = rb_string_value(&RARRAY_PTR($input)[i]);
$1[i] = RSTRING_PTR(str);
$2[i] = RSTRING_LEN(str);
}
}
@ -58,16 +60,20 @@
// Generic strings
%typemap(in) (const char *str, size_t len) {
$1 = STR2CSTR($input);
$2 = (size_t) RSTRING_LEN($input);
VALUE str;
str = rb_string_value(&$input);
$1 = RSTRING_PTR(str);
$2 = RSTRING_LEN(str);
};
// Void type strings without lengths for prefix_key callback
%typemap(in) (void *data) {
if ( (size_t) RSTRING_LEN($input) == 0) {
VALUE str;
str = rb_string_value(&$input);
if (RSTRING_LEN(str) == 0) {
$1 = NULL;
} else {
$1 = STR2CSTR($input);
$1 = RSTRING_PTR(str);
}
};
@ -80,11 +86,12 @@
// Key strings with same master key
// This will have to go if people actually want to set the master key separately
%typemap(in) (const char *master_key, size_t master_key_length, const char *key, size_t key_length) {
$3 = $1 = STR2CSTR($input);
$4 = $2 = (size_t) RSTRING_LEN($input);
VALUE str;
str = rb_string_value(&$input);
$3 = $1 = RSTRING_PTR(str);
$4 = $2 = RSTRING_LEN(str);
};
//// Output maps
%apply unsigned short *OUTPUT {memcached_return *error}
@ -140,6 +147,7 @@
%include "libmemcached/memcached_server.h"
%include "libmemcached/memcached_sasl.h"
%include "libmemcached/memcached_touch.h"
%include "libmemcached/memcached_exist.h"
//// Custom C functions
@ -247,4 +255,3 @@ VALUE memcached_generate_hash_rvalue(const char *key, size_t key_length,memcache
fprintf(stderr, "Failed to initialized SASL.\n");
}
%}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,6 +1,12 @@
require File.expand_path("#{File.dirname(__FILE__)}/../test_helper")
class NilClass
def to_str
"error"
end
end
class MemcachedTest < Test::Unit::TestCase
def setup
@ -265,6 +271,15 @@ class MemcachedTest < Test::Unit::TestCase
end
end
def test_get_coerces_string_type
assert_raises(Memcached::NotFound) do
@cache.get nil
end
assert_raises(TypeError) do
@cache.get 1
end
end
def test_get_with_server_timeout
socket = stub_server 43047
cache = Memcached.new("localhost:43047:1", :timeout => 0.5, :exception_retry_limit => 0)
@ -408,9 +423,12 @@ class MemcachedTest < Test::Unit::TestCase
@cache.get(["#{key}_1"], false))
end
def test_get_multi_checks_types
assert_raises(TypeError, ArgumentError) do
@cache.get([nil])
def test_get_multi_coerces_string_type
assert_nothing_raised do
@cache.get [nil]
end
assert_raises(TypeError) do
@cache.get [1]
end
end
@ -522,6 +540,16 @@ class MemcachedTest < Test::Unit::TestCase
end
end
def test_set_coerces_string_type
assert_nothing_raised do
@cache.set nil, @value
end
assert_raises(TypeError) do
@cache.set 1, @value
end
end
def disabled_test_set_retry_on_client_error
# FIXME Test passes, but Mocha doesn't restore the original method properly
Rlibmemcached.stubs(:memcached_set).raises(Memcached::ClientError)
@ -1342,4 +1370,3 @@ class MemcachedTest < Test::Unit::TestCase
end
end