client libraries updated

This commit is contained in:
antirez 2009-06-16 16:45:04 +02:00
parent df3fd8d88d
commit 111d9959c0
16 changed files with 165 additions and 86 deletions

View File

@ -30,7 +30,6 @@
:requests) :requests)
(defmacro defbenchmark [name & body] (defmacro defbenchmark [name & body]
(let [benchmark-name (symbol (str name "-benchmark"))] (let [benchmark-name (symbol (str name "-benchmark"))]
`(def ~(with-meta benchmark-name {:benchmark true}) `(def ~(with-meta benchmark-name {:benchmark true})
@ -64,7 +63,7 @@
(redis/get (str "key-" (rand-int 1000)))) (redis/get (str "key-" (rand-int 1000))))
(defbenchmark set (defbenchmark set
(redis/set (str "key-" (rand-int 1000)) "blahojga!")) (redis/set (str "key-" (rand-int 1000)) "abc"))
(defbenchmark exists-set-and-get (defbenchmark exists-set-and-get
(let [key (str "key-" (rand-int 100))] (let [key (str "key-" (rand-int 100))]
@ -77,7 +76,7 @@
:host "127.0.0.1" :host "127.0.0.1"
:port 6379 :port 6379
:db 15 :db 15
:clients 4 :clients 1
:requests 10000)) :requests 10000))
(defn create-clients [options] (defn create-clients [options]
@ -103,9 +102,14 @@
(defn report-request-times [clients requests] (defn report-request-times [clients requests]
(let [requests-dist (map #(let [perc (* 100 (/ (last %) requests))] (let [requests-dist (map #(let [perc (* 100 (/ (last %) requests))]
(conj % perc)) (requests-by-ms clients))] (conj % perc)) (requests-by-ms clients))]
(dorun (loop [items requests-dist
(map #(println (format "%.2f%% < %d ms" (float (last %)) (inc (first %)))) seen 0]
requests-dist)))) (if-not (empty? items)
(do
(let [item (first items)
seen (+ seen (last item))]
(println (format "%.2f%% < %d ms" (float seen) (inc (first item))))
(recur (rest items) seen)))))))
(defn report-client-rps [client] (defn report-client-rps [client]
(let [{:keys [id requests-performed request-times]} @client] (let [{:keys [id requests-performed request-times]} @client]
@ -128,7 +132,7 @@
(println (format "====== %s =====\n" name)) (println (format "====== %s =====\n" name))
(println (format " %d requests completed in %f seconds\n" requests time-in-seconds)) (println (format " %d requests completed in %f seconds\n" requests time-in-seconds))
(println (format " %d parallel clients\n" (:clients options))) (println (format " %d parallel clients\n" (:clients options)))
;(report-request-times clients requests) (report-request-times clients requests)
;(dorun (map report-client-rps clients)) ;(dorun (map report-client-rps clients))
(println (format "%f requests per second\n\n" requests-per-second)) (println (format "%f requests per second\n\n" requests-per-second))
) )

View File

@ -1,10 +1,9 @@
(ns benchmarks.ruby (ns benchmarks.ruby
(:require redis)) (:require redis))
(dotimes [n 4]
(dotimes [n 2]
(redis/with-server (redis/with-server
{} {:db 15}
(redis/set "foo" "The first line we sent to the server is some text") (redis/set "foo" "The first line we sent to the server is some text")
(time (time
(dotimes [i 20000] (dotimes [i 20000]

View File

@ -38,8 +38,8 @@
<target name="jar" description="Create jar file" depends="compile"> <target name="jar" description="Create jar file" depends="compile">
<jar jarfile="${redis-clojure.jar}"> <jar jarfile="${redis-clojure.jar}">
<path location="LICENSE"/> <path location="LICENSE"/>
<fileset dir="${source.dir}" includes="**/*.clj"/> <!--<fileset dir="${source.dir}" includes="**/*.clj"/>-->
<!--<fileset dir="${build.dir}" includes="**/*.class"/>--> <fileset dir="${build.dir}" includes="**/*.class"/>
<manifest> <manifest>
<attribute name="Built-By" value="${user.name}"/> <attribute name="Built-By" value="${user.name}"/>
</manifest> </manifest>
@ -65,6 +65,7 @@
<classpath> <classpath>
<path location="${basedir}"/> <path location="${basedir}"/>
<path location="${source.dir}"/> <path location="${source.dir}"/>
<!--<path location="${redis-clojure.jar}"/>-->
<path location="${clojure.jar}"/> <path location="${clojure.jar}"/>
<path location="${clojure-contrib.jar}"/> <path location="${clojure-contrib.jar}"/>
</classpath> </classpath>

View File

@ -1,11 +1,11 @@
;(add-classpath "file:///Users/ragge/Projects/clojure/redis-clojure/src/") ;(add-classpath "file:///Users/ragge/Projects/clojure/redis-clojure/src/")
(set! *warn-on-reflection* true)
(ns redis (ns redis
(:refer-clojure :exclude [get set type keys sort]) (:refer-clojure :exclude [get set type keys sort])
(:use redis.internal)) (:use redis.internal))
;(set! *warn-on-reflection* true)
(defmacro with-server (defmacro with-server
"Evaluates body in the context of a new connection to a Redis server "Evaluates body in the context of a new connection to a Redis server
then closes the connection. then closes the connection.
@ -100,6 +100,7 @@
;; Set commands ;; Set commands
(sadd [key member] :bulk int-to-bool) (sadd [key member] :bulk int-to-bool)
(srem [key member] :bulk int-to-bool) (srem [key member] :bulk int-to-bool)
(spop [key] :inline)
(smove [srckey destkey member] :bulk int-to-bool) (smove [srckey destkey member] :bulk int-to-bool)
(scard [key] :inline) (scard [key] :inline)
(sismember [key member] :bulk int-to-bool) (sismember [key member] :bulk int-to-bool)
@ -122,6 +123,7 @@
(bgsave [] :inline) (bgsave [] :inline)
(lastsave [] :inline int-to-date) (lastsave [] :inline int-to-date)
(shutdown [] :inline) (shutdown [] :inline)
;; Remote control
(info [] :inline string-to-map) (info [] :inline string-to-map)
;;(monitor [] :inline)) ;;(monitor [] :inline))
) )

View File

@ -39,7 +39,8 @@
(let [{:keys [host port timeout]} server (let [{:keys [host port timeout]} server
socket (Socket. #^String host #^Integer port)] socket (Socket. #^String host #^Integer port)]
(doto socket (doto socket
(.setTcpNoDelay true)))) (.setTcpNoDelay true)
(.setKeepAlive true))))
(defn with-server* (defn with-server*
[server-spec func] [server-spec func]
@ -99,8 +100,7 @@
(defn reply-type (defn reply-type
([#^BufferedReader reader] ([#^BufferedReader reader]
(let [type (char (.read reader))] (char (.read reader))))
type)))
(defmulti parse-reply reply-type :default :unknown) (defmulti parse-reply reply-type :default :unknown)

View File

@ -214,20 +214,25 @@
(redis/lset "list" -1 "test3") (redis/lset "list" -1 "test3")
(is (= "test3" (redis/lindex "list" 2)))) (is (= "test3" (redis/lindex "list" 2))))
;; TBD
(deftest lrem (deftest lrem
(is (thrown? Exception (redis/lrem "foo" 0 "bar"))) (is (thrown? Exception (redis/lrem "foo" 0 "bar")))
(is (= 0 (redis/lrem "list" 0 "")))) (is (= 0 (redis/lrem "newlist" 0 "")))
(is (= 1 (redis/lrem "list" 1 "two")))
(is (= 1 (redis/lrem "list" 42 "three")))
(is (= 1 (redis/llen "list"))))
(deftest lpop (deftest lpop
(is (thrown? Exception (redis/lpop "foo"))) (is (thrown? Exception (redis/lpop "foo")))
(is (= "one" (redis/lpop "list")))) (is (= nil (redis/lpop "newlist")))
(is (= "one" (redis/lpop "list")))
(is (= 2 (redis/llen "list"))))
(deftest rpop (deftest rpop
(is (thrown? Exception (redis/rpop "foo"))) (is (thrown? Exception (redis/rpop "foo")))
(is (= "three" (redis/rpop "list")))) (is (= nil (redis/rpop "newlist")))
(is (= "three" (redis/rpop "list")))
(is (= 2 (redis/llen "list"))))
;; ;;
;; Set commands ;; Set commands
@ -242,11 +247,16 @@
(deftest srem (deftest srem
(is (thrown? Exception (redis/srem "foo" "bar"))) (is (thrown? Exception (redis/srem "foo" "bar")))
(is (thrown? Exception (redis/srem "newset" "member"))) (is (= false (redis/srem "newset" "member")))
(is (= true (redis/srem "set" "two"))) (is (= true (redis/srem "set" "two")))
(is (= false (redis/sismember "set" "two"))) (is (= false (redis/sismember "set" "two")))
(is (= false (redis/srem "set" "blahonga")))) (is (= false (redis/srem "set" "blahonga"))))
(deftest spop
(is (thrown? Exception (redis/spop "foo" "bar")))
(is (= nil (redis/spop "newset")))
(is (contains? #{"one" "two" "three"} (redis/spop "set"))))
(deftest smove (deftest smove
(is (thrown? Exception (redis/smove "foo" "set" "one"))) (is (thrown? Exception (redis/smove "foo" "set" "one")))
(is (thrown? Exception (redis/smove "set" "foo" "one"))) (is (thrown? Exception (redis/smove "set" "foo" "one")))

View File

@ -4,11 +4,6 @@
(:import [java.io StringReader BufferedReader])) (:import [java.io StringReader BufferedReader]))
;; ;;
;; Helpers ;; Helpers
;; ;;

View File

@ -1,6 +1,12 @@
general:
- check for complete support for 0.100 (compiles; existing tests pass)
command handlers: command handlers:
- support DEL as vararg - support DEL as vararg
- support MLLEN and MSCARD - support MLLEN and MSCARD
- support SDIFF
- support SDIFFSTORE
unit tests: unit tests:
- sort with limit - sort with limit

View File

@ -40,7 +40,6 @@
#endif #endif
#include <cstring> #include <cstring>
#include <cstdlib>
#include <cassert> #include <cassert>
#include <sys/errno.h> #include <sys/errno.h>
@ -236,32 +235,15 @@ namespace
return rtrim(line, CRLF); return rtrim(line, CRLF);
} }
unsigned long unsigned_number_from_string(const string & data) template <typename T>
T value_from_string(const string & data)
{ {
errno = 0; T value;
unsigned long value = strtoul(data.c_str(), NULL, 10); istringstream iss(data);
iss >> value;
if (value == ULONG_MAX && errno == ERANGE) if (iss.fail())
throw redis::value_error("invalid number; out of range of long"); throw redis::value_error("invalid number");
if (value == 0 && errno == EINVAL)
throw redis::value_error("invalid number; unrecognized format");
return value;
}
redis::client::int_type number_from_string(const string & data)
{
errno = 0;
redis::client::int_type value = strtol(data.c_str(), NULL, 10);
if ((value == LONG_MAX || value == LONG_MIN) && errno == ERANGE)
throw redis::value_error("invalid number; out of range of long");
if (value == 0 && errno == EINVAL)
throw redis::value_error("invalid number; unrecognized format");
return value; return value;
} }
@ -284,6 +266,10 @@ namespace
const string server_info_key_total_commands_processed = "total_commands_processed"; const string server_info_key_total_commands_processed = "total_commands_processed";
const string server_info_key_uptime_in_seconds = "uptime_in_seconds"; const string server_info_key_uptime_in_seconds = "uptime_in_seconds";
const string server_info_key_uptime_in_days = "uptime_in_days"; const string server_info_key_uptime_in_days = "uptime_in_days";
const string server_info_key_role = "role";
const string server_info_value_role_master = "master";
const string server_info_value_role_slave = "slave";
} }
namespace redis namespace redis
@ -578,11 +564,11 @@ namespace redis
return recv_multi_bulk_reply_(out); return recv_multi_bulk_reply_(out);
} }
void client::sinterstore(const client::string_type & dstkey, client::int_type client::sinterstore(const client::string_type & dstkey,
const client::string_vector & keys) const client::string_vector & keys)
{ {
send_(makecmd("SINTERSTORE") << dstkey << ' ' << keys); send_(makecmd("SINTERSTORE") << dstkey << ' ' << keys);
recv_ok_reply_(); return recv_int_reply_();
} }
client::int_type client::sunion(const client::string_vector & keys, client::int_type client::sunion(const client::string_vector & keys,
@ -592,11 +578,11 @@ namespace redis
return recv_multi_bulk_reply_(out); return recv_multi_bulk_reply_(out);
} }
void client::sunionstore(const client::string_type & dstkey, client::int_type client::sunionstore(const client::string_type & dstkey,
const client::string_vector & keys) const client::string_vector & keys)
{ {
send_(makecmd("SUNIONSTORE") << dstkey << ' ' << keys); send_(makecmd("SUNIONSTORE") << dstkey << ' ' << keys);
recv_ok_reply_(); return recv_int_reply_();
} }
client::int_type client::smembers(const client::string_type & key, client::int_type client::smembers(const client::string_type & key,
@ -746,25 +732,27 @@ namespace redis
if (key == server_info_key_version) if (key == server_info_key_version)
out.version = val; out.version = val;
else if (key == server_info_key_bgsave_in_progress) else if (key == server_info_key_bgsave_in_progress)
out.bgsave_in_progress = unsigned_number_from_string(val) == 1; out.bgsave_in_progress = value_from_string<unsigned long>(val) == 1;
else if (key == server_info_key_connected_clients) else if (key == server_info_key_connected_clients)
out.connected_clients = unsigned_number_from_string(val); out.connected_clients = value_from_string<unsigned long>(val);
else if (key == server_info_key_connected_slaves) else if (key == server_info_key_connected_slaves)
out.connected_slaves = unsigned_number_from_string(val); out.connected_slaves = value_from_string<unsigned long>(val);
else if (key == server_info_key_used_memory) else if (key == server_info_key_used_memory)
out.used_memory = unsigned_number_from_string(val); out.used_memory = value_from_string<unsigned long>(val);
else if (key == server_info_key_changes_since_last_save) else if (key == server_info_key_changes_since_last_save)
out.changes_since_last_save = unsigned_number_from_string(val); out.changes_since_last_save = value_from_string<unsigned long>(val);
else if (key == server_info_key_last_save_time) else if (key == server_info_key_last_save_time)
out.last_save_time = unsigned_number_from_string(val); out.last_save_time = value_from_string<unsigned long>(val);
else if (key == server_info_key_total_connections_received) else if (key == server_info_key_total_connections_received)
out.total_connections_received = unsigned_number_from_string(val); out.total_connections_received = value_from_string<unsigned long>(val);
else if (key == server_info_key_total_commands_processed) else if (key == server_info_key_total_commands_processed)
out.total_commands_processed = unsigned_number_from_string(val); out.total_commands_processed = value_from_string<unsigned long>(val);
else if (key == server_info_key_uptime_in_seconds) else if (key == server_info_key_uptime_in_seconds)
out.uptime_in_seconds = unsigned_number_from_string(val); out.uptime_in_seconds = value_from_string<unsigned long>(val);
else if (key == server_info_key_uptime_in_days) else if (key == server_info_key_uptime_in_days)
out.uptime_in_days = unsigned_number_from_string(val); out.uptime_in_days = value_from_string<unsigned long>(val);
else if (key == server_info_key_role)
out.role = val == server_info_value_role_master ? role_master : role_slave;
else else
throw protocol_error(string("unexpected info key '") + key + "'"); throw protocol_error(string("unexpected info key '") + key + "'");
} }
@ -826,7 +814,7 @@ namespace redis
if (line[0] != prefix) if (line[0] != prefix)
throw protocol_error("unexpected prefix for bulk reply"); throw protocol_error("unexpected prefix for bulk reply");
return number_from_string(line.substr(1)); return value_from_string<client::int_type>(line.substr(1));
} }
string client::recv_bulk_reply_() string client::recv_bulk_reply_()
@ -895,7 +883,7 @@ namespace redis
if (line[0] != prefix_int_reply) if (line[0] != prefix_int_reply)
throw protocol_error("unexpected prefix for integer reply"); throw protocol_error("unexpected prefix for integer reply");
return number_from_string(line.substr(1)); return value_from_string<client::int_type>(line.substr(1));
} }
void client::recv_int_ok_reply_() void client::recv_int_ok_reply_()

View File

@ -39,6 +39,12 @@
namespace redis namespace redis
{ {
enum server_role
{
role_master,
role_slave
};
struct server_info struct server_info
{ {
std::string version; std::string version;
@ -52,6 +58,7 @@ namespace redis
unsigned long total_commands_processed; unsigned long total_commands_processed;
unsigned long uptime_in_seconds; unsigned long uptime_in_seconds;
unsigned long uptime_in_days; unsigned long uptime_in_days;
server_role role;
}; };
// Generic error that is thrown when communicating with the redis server. // Generic error that is thrown when communicating with the redis server.
@ -355,8 +362,9 @@ namespace redis
// Compute the intersection between the sets stored at key1, key2, ..., // Compute the intersection between the sets stored at key1, key2, ...,
// keyN, and store the resulting set at dstkey // keyN, and store the resulting set at dstkey
// Returns the number of items in the intersection
void sinterstore(const string_type & dstkey, const string_vector & keys); int_type sinterstore(const string_type & dstkey, const string_vector & keys);
// Return the union between the sets stored at key1, key2, ..., keyN // Return the union between the sets stored at key1, key2, ..., keyN
@ -364,8 +372,9 @@ namespace redis
// Compute the union between the sets stored at key1, key2, ..., keyN, // Compute the union between the sets stored at key1, key2, ..., keyN,
// and store the resulting set at dstkey // and store the resulting set at dstkey
// Returns the number of items in the intersection
void sunionstore(const string_type & dstkey, const string_vector & keys); int_type sunionstore(const string_type & dstkey, const string_vector & keys);
// Return all the members of the set value at key // Return all the members of the set value at key

View File

@ -478,7 +478,7 @@ int main(int argc, char ** argv)
keys.push_back("seta"); keys.push_back("seta");
keys.push_back("setb"); keys.push_back("setb");
c.sinterstore("setc", keys); ASSERT_EQUAL(c.sinterstore("setc", keys), 2L);
redis::client::string_set members; redis::client::string_set members;
ASSERT_EQUAL(c.smembers("setc", members), 2L); ASSERT_EQUAL(c.smembers("setc", members), 2L);
@ -510,7 +510,7 @@ int main(int argc, char ** argv)
keys.push_back("setf"); keys.push_back("setf");
keys.push_back("setg"); keys.push_back("setg");
c.sunionstore("seth", keys); ASSERT_EQUAL(c.sunionstore("seth", keys), 2L);
redis::client::string_set members; redis::client::string_set members;
ASSERT_EQUAL(c.smembers("seth", members), 2L); ASSERT_EQUAL(c.smembers("seth", members), 2L);

View File

@ -239,6 +239,7 @@ redis_commands = {
set_preserve = bulk('SETNX', toboolean), set_preserve = bulk('SETNX', toboolean),
get = inline('GET'), get = inline('GET'),
get_multiple = inline('MGET'), get_multiple = inline('MGET'),
get_set = bulk('GETSET'),
increment = inline('INCR'), increment = inline('INCR'),
increment_by = inline('INCRBY'), increment_by = inline('INCRBY'),
decrement = inline('DECR'), decrement = inline('DECR'),
@ -262,6 +263,7 @@ redis_commands = {
rename_preserve = inline('RENAMENX'), rename_preserve = inline('RENAMENX'),
expire = inline('EXPIRE', toboolean), expire = inline('EXPIRE', toboolean),
database_size = inline('DBSIZE'), database_size = inline('DBSIZE'),
time_to_live = inline('TTL'),
-- commands operating on lists -- commands operating on lists
push_tail = bulk('RPUSH'), push_tail = bulk('RPUSH'),
@ -276,12 +278,17 @@ redis_commands = {
pop_last = inline('RPOP'), pop_last = inline('RPOP'),
-- commands operating on sets -- commands operating on sets
set_add = inline('SADD'), set_add = bulk('SADD'),
set_remove = inline('SREM'), set_remove = bulk('SREM'),
set_move = bulk('SMOVE'),
set_cardinality = inline('SCARD'), set_cardinality = inline('SCARD'),
set_is_member = inline('SISMEMBER'), set_is_member = inline('SISMEMBER'),
set_intersection = inline('SINTER'), set_intersection = inline('SINTER'),
set_intersection_store = inline('SINTERSTORE'), set_intersection_store = inline('SINTERSTORE'),
set_union = inline('SUNION'),
set_union_store = inline('SUNIONSTORE'),
set_diff = inline('SDIFF'),
set_diff_store = inline('SDIFFSTORE'),
set_members = inline('SMEMBERS'), set_members = inline('SMEMBERS'),
-- multiple databases handling commands -- multiple databases handling commands
@ -331,4 +338,10 @@ redis_commands = {
return info return info
end end
), ),
slave_of = inline('SLAVEOF'),
slave_of_no_one = custom('SLAVEOF',
function(client, command)
return request.inline(client, command, 'NO ONE')
end
),
} }

View File

@ -2,4 +2,5 @@ nohup.out
redis/* redis/*
rdsrv rdsrv
pkg/* pkg/*
coverage/*
.idea .idea

View File

@ -8,7 +8,7 @@ require 'tasks/redis.tasks'
GEM = 'redis' GEM = 'redis'
GEM_NAME = 'redis' GEM_NAME = 'redis'
GEM_VERSION = '0.0.3.4' GEM_VERSION = '0.1'
AUTHORS = ['Ezra Zygmuntowicz', 'Taylor Weibley', 'Matthew Clark'] AUTHORS = ['Ezra Zygmuntowicz', 'Taylor Weibley', 'Matthew Clark']
EMAIL = "ez@engineyard.com" EMAIL = "ez@engineyard.com"
HOMEPAGE = "http://github.com/ezmobius/redis-rb" HOMEPAGE = "http://github.com/ezmobius/redis-rb"
@ -54,3 +54,9 @@ task :make_spec do
file.puts spec.to_ruby file.puts spec.to_ruby
end end
end end
desc "Run all examples with RCov"
Spec::Rake::SpecTask.new(:rcov) do |t|
t.spec_files = FileList['spec/**/*_spec.rb']
t.rcov = true
end

View File

@ -29,7 +29,11 @@ describe "redis" do
@r.quit @r.quit
end end
it 'should be able to PING' do it "should be able connect without a timeout" do
lambda { Redis.new :timeout => 0 }.should_not raise_error
end
it "should be able to PING" do
@r.ping.should == 'PONG' @r.ping.should == 'PONG'
end end
@ -62,6 +66,11 @@ describe "redis" do
@r['foo'].should == nil @r['foo'].should == nil
end end
it "should be able to return a TTL for a key" do
@r.set('foo', 'bar', 1)
@r.ttl('foo').should == 1
end
it "should be able to SETNX" do it "should be able to SETNX" do
@r['foo'] = 'nik' @r['foo'] = 'nik'
@r['foo'].should == 'nik' @r['foo'].should == 'nik'
@ -69,6 +78,11 @@ describe "redis" do
@r['foo'].should == 'nik' @r['foo'].should == 'nik'
end end
# #
it "should be able to GETSET" do
@r.getset('foo', 'baz').should == 'bar'
@r['foo'].should == 'baz'
end
#
it "should be able to INCR a key" do it "should be able to INCR a key" do
@r.del('counter') @r.del('counter')
@r.incr('counter').should == 1 @r.incr('counter').should == 1
@ -76,6 +90,13 @@ describe "redis" do
@r.incr('counter').should == 3 @r.incr('counter').should == 3
end end
# #
it "should be able to INCRBY a key" do
@r.del('counter')
@r.incrby('counter', 1).should == 1
@r.incrby('counter', 2).should == 3
@r.incrby('counter', 3).should == 6
end
#
it "should be able to DECR a key" do it "should be able to DECR a key" do
@r.del('counter') @r.del('counter')
@r.incr('counter').should == 1 @r.incr('counter').should == 1
@ -137,6 +158,10 @@ describe "redis" do
@r['foo'] = 'qux' @r['foo'] = 'qux'
@r.keys("f*").sort.should == ['f','fo', 'foo'].sort @r.keys("f*").sort.should == ['f','fo', 'foo'].sort
end end
#
it "should be able to return a random key (RANDOMKEY)" do
3.times { @r.exists(@r.randomkey).should be_true }
end
#BTM - TODO #BTM - TODO
it "should be able to check the TYPE of a key" do it "should be able to check the TYPE of a key" do
@r['foo'] = 'nik' @r['foo'] = 'nik'
@ -356,13 +381,13 @@ describe "redis" do
@r.sort('dogs', :get => ['dog:*:name', 'dog:*:breed'], :limit => [0,1], :order => 'desc alpha').should == ['taj', 'terrier'] @r.sort('dogs', :get => ['dog:*:name', 'dog:*:breed'], :limit => [0,1], :order => 'desc alpha').should == ['taj', 'terrier']
end end
# #
it "should provide info" do it "should provide info (INFO)" do
[:last_save_time, :redis_version, :total_connections_received, :connected_clients, :total_commands_processed, :connected_slaves, :uptime_in_seconds, :used_memory, :uptime_in_days, :changes_since_last_save].each do |x| [:last_save_time, :redis_version, :total_connections_received, :connected_clients, :total_commands_processed, :connected_slaves, :uptime_in_seconds, :used_memory, :uptime_in_days, :changes_since_last_save].each do |x|
@r.info.keys.should include(x) @r.info.keys.should include(x)
end end
end end
# #
it "should be able to flush the database" do it "should be able to flush the database (FLUSHDB)" do
@r['key1'] = 'keyone' @r['key1'] = 'keyone'
@r['key2'] = 'keytwo' @r['key2'] = 'keytwo'
@r.keys('*').sort.should == ['foo', 'key1', 'key2'].sort #foo from before @r.keys('*').sort.should == ['foo', 'key1', 'key2'].sort #foo from before
@ -370,6 +395,10 @@ describe "redis" do
@r.keys('*').should == [] @r.keys('*').should == []
end end
# #
it "should raise exception when manually try to change the database" do
lambda { @r.select(0) }.should raise_error
end
#
it "should be able to provide the last save time (LASTSAVE)" do it "should be able to provide the last save time (LASTSAVE)" do
savetime = @r.lastsave savetime = @r.lastsave
Time.at(savetime).class.should == Time Time.at(savetime).class.should == Time
@ -387,6 +416,10 @@ describe "redis" do
@r.bgsave.should == 'OK' @r.bgsave.should == 'OK'
end end
it "should should be able to ECHO" do
@r.echo("message in a bottle\n").should == "message in a bottle\n"
end
it "should handle multiple servers" do it "should handle multiple servers" do
require 'dist_redis' require 'dist_redis'
@r = DistRedis.new(:hosts=> ['localhost:6379', '127.0.0.1:6379'], :db => 15) @r = DistRedis.new(:hosts=> ['localhost:6379', '127.0.0.1:6379'], :db => 15)

View File

@ -0,0 +1,12 @@
#!/bin/sh
rm -rf temp
mkdir temp
cd temp
git clone git://github.com/ragnard/redis-clojure.git
cd redis-clojure
rm -rf .git
cd ..
cd ..
rm -rf clojure
mv temp/redis-clojure clojure
rm -rf temp