/
tokyotyrant.rb
140 lines (115 loc) · 3.16 KB
/
tokyotyrant.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
require 'tokyotyrant'
require 'rubygems'
require 'classx'
module Todoit
module Model
# wrapper for TokyoTyrant::RDB.
class TokyoTyrant
include ClassX
class ConnectionError < RuntimeError; end
class Error < RuntimeError; end
StorageType = ::TokyoTyrant::RDBTBL
has :host,
:default => "127.0.0.1"
has :port,
:default => 1978
has :name_space,
:default => 'todoit_'
has :rdb,
:lazy => true,
:handles => %w[ put get mget out genuid ],
:default => lambda {|mine|
mine.class.connect(mine.host, mine.port)
}
def self.connect host, port
tt = StorageType.new
tt.open(host, port) or
raise ConnectionError, tt.errmsg
tt
end
def close
self.rdb.close
self.rdb = nil
end
def reconnect
self.close
self.rdb = self.class.connect(self.host, self.port)
end
def after_init
self.rdb # for creating connection for tokyotyrant in initaize.
end
%w[ out get ].each do |meth|
define_method meth do |key|
begin
key = "#{self.name_space}#{key}"
self.rdb.__send__(meth, key) or
raise_exeption(self.rdb.ecode)
rescue ConnectionError => e
reconnect
retry
end
end
end
%w[ put putkeep putcat putnr ].each do |meth|
define_method meth do |key, val|
begin
key = "#{self.name_space}#{key}"
self.rdb.__send__(meth, key, val) or
raise_exeption(self.rdb.ecode)
rescue ConnectionError => e
reconnect
retry
end
end
end
def fwmkeys prefix, max=-1
prefix = "#{self.name_space}#{prefix}"
result = self.rdb.fwmkeys(prefix, max)
if result.size == 0
raise_exeption(self.rdb.ecode)
end
result
rescue ConnectionError => e
reconnect
retry
end
alias get_keys fwmkeys
def get_like prefix, max=-1
result = get_keys(prefix, max)
get_multi(result)
end
def get_multi with_prefix_keys
hash = {}
with_prefix_keys.each do |key|
hash[key] = nil
end
raise_exeption(self.rdb.ecode) if self.rdb.mget(hash) < 0
# for ruby 1.9.1
if ''.respond_to? :force_encoding
hash.each do |key,val|
val.each do |k,v|
v.force_encoding('UTF-8')
end
end
end
hash
rescue ConnectionError => e
retry
end
def raise_exeption ecode
case ecode
when StorageType::EKEEP, StorageType::ENOREC, StorageType::EMISC, StorageType::ESUCCESS
# pass
when StorageType::EREFUSED,
StorageType::ESEND,
StorageType::ERECV
raise ConnectionError, self.rdb.errmsg
when StorageType::EINVALID, StorageType::ENOHOST
raise "some thing wrong: #{self.rdb.inspect}"
else
raise "unknown ecode: #{ecode}"
end
end
end
end
end