rufus-tokyo 0.1.5 → 0.1.6
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.txt +12 -0
- data/README.txt +89 -54
- data/lib/rufus/tokyo.rb +6 -5
- data/lib/rufus/tokyo/cabinet.rb +4 -4
- data/lib/rufus/tokyo/cabinet/lib.rb +15 -9
- data/lib/rufus/tokyo/cabinet/table.rb +83 -35
- data/lib/rufus/tokyo/cabinet/util.rb +22 -1
- data/lib/rufus/tokyo/dystopia.rb +2 -2
- data/lib/rufus/tokyo/dystopia/lib.rb +17 -22
- data/lib/rufus/tokyo/tyrant.rb +56 -3
- data/lib/rufus/tokyo/tyrant/abstract.rb +10 -1
- data/lib/rufus/tokyo/tyrant/lib.rb +52 -57
- data/lib/rufus/tokyo/tyrant/table.rb +29 -16
- metadata +2 -2
data/CHANGELOG.txt
CHANGED
@@ -2,6 +2,18 @@
|
|
2
2
|
= rufus-tokyo CHANGELOG.txt
|
3
3
|
|
4
4
|
|
5
|
+
== rufus-tokyo - 0.1.6 released 2009/02/16
|
6
|
+
|
7
|
+
- todo : Tyrant and TyrantTable now complain when used in lieu of each other
|
8
|
+
- todo : implemented Tyrant and TyrantTable #stat
|
9
|
+
- todo : made tran begin/abort/commit directly available (framework builders)
|
10
|
+
- todo : implemented Rufus::Tokyo::Table#transaction
|
11
|
+
- bug : JRuby support back in
|
12
|
+
- todo : implemented Rufus::Tokyo::Map#[] (class method)
|
13
|
+
- todo : simplified Table and TyrantTable #[]=
|
14
|
+
- bug : preventing table#[]= from segfaulting on bad input (Justin)
|
15
|
+
|
16
|
+
|
5
17
|
== rufus-tokyo - 0.1.5 released 2009/02/13
|
6
18
|
|
7
19
|
- todo : implemented set_index (cabinet / tyrant tables)
|
data/README.txt
CHANGED
@@ -47,32 +47,54 @@ http://tokyocabinet.sourceforge.net/spex-en.html#tctdbapi
|
|
47
47
|
|
48
48
|
require 'rubygems'
|
49
49
|
require 'rufus/tokyo'
|
50
|
-
|
51
|
-
t = Rufus::Tokyo::Table.new('table.tdb'
|
52
|
-
|
50
|
+
|
51
|
+
t = Rufus::Tokyo::Table.new('table.tdb')
|
52
|
+
|
53
53
|
t['pk0'] = { 'name' => 'alfred', 'age' => '22' }
|
54
54
|
t['pk1'] = { 'name' => 'bob', 'age' => '18' }
|
55
55
|
t['pk2'] = { 'name' => 'charly', 'age' => '45' }
|
56
56
|
t['pk3'] = { 'name' => 'doug', 'age' => '77' }
|
57
57
|
t['pk4'] = { 'name' => 'ephrem', 'age' => '32' }
|
58
|
-
|
58
|
+
|
59
59
|
p t.query { |q|
|
60
60
|
q.add_condition 'age', :numge, '32'
|
61
61
|
q.order_by 'age'
|
62
62
|
}
|
63
63
|
# => [ {"name"=>"ephrem", :pk=>"pk4", "age"=>"32"},
|
64
64
|
# {"name"=>"charly", :pk=>"pk2", "age"=>"45"} ]
|
65
|
-
|
65
|
+
|
66
66
|
t.close
|
67
67
|
|
68
|
+
Note that the Tokyo Cabinet Table API does support transactions :
|
69
|
+
|
70
|
+
p t.size
|
71
|
+
# => 0
|
72
|
+
|
73
|
+
t.transaction do
|
74
|
+
t['pk0'] = { 'name' => 'alfred', 'age' => '22' }
|
75
|
+
t['pk1'] = { 'name' => 'bob', 'age' => '18' }
|
76
|
+
t.abort
|
77
|
+
end
|
78
|
+
|
79
|
+
p t.size
|
80
|
+
# => 0
|
81
|
+
|
82
|
+
|
68
83
|
=== TT remote db
|
69
84
|
|
70
85
|
http://tokyocabinet.sourceforge.net/tyrantdoc/
|
71
86
|
|
87
|
+
to start a ttserver (backed by a hash), on the command line
|
88
|
+
|
89
|
+
ttserver -port 45001 data.tch
|
90
|
+
|
91
|
+
|
92
|
+
then, in Ruby :
|
93
|
+
|
72
94
|
require 'rubygems'
|
73
|
-
require 'rufus/tokyo'
|
95
|
+
require 'rufus/tokyo/tyrant'
|
74
96
|
|
75
|
-
db = Rufus::Tokyo::Tyrant.new('
|
97
|
+
db = Rufus::Tokyo::Tyrant.new('localhost', 45001)
|
76
98
|
|
77
99
|
db['nada'] = 'surf'
|
78
100
|
|
@@ -82,31 +104,76 @@ http://tokyocabinet.sourceforge.net/tyrantdoc/
|
|
82
104
|
db.close
|
83
105
|
|
84
106
|
|
107
|
+
Rufus::Tokyo::Tyrant instances have a #stat method :
|
108
|
+
|
109
|
+
puts db.stat.inject('') { |s, (k, v)| s << "#{k} => #{v}\n" }
|
110
|
+
# =>
|
111
|
+
# pid => 7566
|
112
|
+
# loadavg => 0.398438
|
113
|
+
# size => 528736
|
114
|
+
# rnum => 0
|
115
|
+
# time => 1234764065.305923
|
116
|
+
# sid => 898521513
|
117
|
+
# type => hash
|
118
|
+
# bigend => 0
|
119
|
+
# ru_sys => 3.398698
|
120
|
+
# version => 1.1.15
|
121
|
+
# ru_user => 2.155215
|
122
|
+
# ru_real => 3218.451152
|
123
|
+
# fd => 7
|
124
|
+
|
125
|
+
|
85
126
|
=== TT remote table
|
86
127
|
|
87
|
-
|
128
|
+
to start a ttserver (backed by a table), on the command line :
|
129
|
+
|
130
|
+
ttserver -port 45002 data.tct
|
131
|
+
|
132
|
+
|
133
|
+
then, in Ruby, much like a local table :
|
88
134
|
|
89
135
|
require 'rubygems'
|
90
|
-
require 'rufus/tokyo'
|
91
|
-
|
92
|
-
t = Rufus::Tokyo::TyrantTable.new('localhost',
|
93
|
-
|
136
|
+
require 'rufus/tokyo/tyrant'
|
137
|
+
|
138
|
+
t = Rufus::Tokyo::TyrantTable.new('localhost', 45002)
|
139
|
+
|
94
140
|
t['pk0'] = { 'name' => 'alfred', 'age' => '22' }
|
95
141
|
t['pk1'] = { 'name' => 'bob', 'age' => '18' }
|
96
142
|
t['pk2'] = { 'name' => 'charly', 'age' => '45' }
|
97
143
|
t['pk3'] = { 'name' => 'doug', 'age' => '77' }
|
98
144
|
t['pk4'] = { 'name' => 'ephrem', 'age' => '32' }
|
99
|
-
|
145
|
+
|
100
146
|
p t.query { |q|
|
101
147
|
q.add_condition 'age', :numge, '32'
|
102
148
|
q.order_by 'age'
|
103
149
|
}
|
104
150
|
# => [ {"name"=>"ephrem", :pk=>"pk4", "age"=>"32"},
|
105
151
|
# {"name"=>"charly", :pk=>"pk2", "age"=>"45"} ]
|
106
|
-
|
152
|
+
|
107
153
|
t.close
|
108
154
|
|
109
155
|
|
156
|
+
Rufus::Tokyo::TyrantTable instances have a #stat method :
|
157
|
+
|
158
|
+
puts t.stat.inject('') { |s, (k, v)| s << "#{k} => #{v}\n" }
|
159
|
+
# =>
|
160
|
+
# pid => 7569
|
161
|
+
# loadavg => 0.295410
|
162
|
+
# size => 935792
|
163
|
+
# rnum => 0
|
164
|
+
# time => 1234764228.942014
|
165
|
+
# sid => 1027604232
|
166
|
+
# type => table
|
167
|
+
# bigend => 0
|
168
|
+
# ru_sys => 5.966750
|
169
|
+
# version => 1.1.15
|
170
|
+
# ru_user => 2.601947
|
171
|
+
# ru_real => 3382.084479
|
172
|
+
# fd => 10
|
173
|
+
|
174
|
+
|
175
|
+
== rdoc
|
176
|
+
|
110
177
|
more in the rdoc
|
111
178
|
|
112
179
|
http://rufus.rubyforge.org/rufus-tokyo/
|
@@ -115,6 +182,8 @@ more in the rdoc
|
|
115
182
|
http://rufus.rubyforge.org/rufus-tokyo/classes/Rufus/Tokyo/Tyrant.html
|
116
183
|
http://rufus.rubyforge.org/rufus-tokyo/classes/Rufus/Tokyo/TyrantTable.html
|
117
184
|
|
185
|
+
don't hesitate to "man ttserver" on the command line.
|
186
|
+
|
118
187
|
or directly in the source
|
119
188
|
|
120
189
|
http://github.com/jmettraux/rufus-tokyo/blob/master/lib/rufus/tokyo/cabinet/abstract.rb
|
@@ -123,62 +192,28 @@ or directly in the source
|
|
123
192
|
http://github.com/jmettraux/rufus-tokyo/blob/master/lib/rufus/tokyo/tyrant/table.rb
|
124
193
|
|
125
194
|
|
126
|
-
== Tokyo Cabinet install
|
127
|
-
|
128
|
-
On a Mac, you would do
|
129
|
-
|
130
|
-
sudo port install tokyocabinet
|
131
|
-
|
132
|
-
|
133
|
-
If you don't have Tokyo Cabinet on your system, you can get it and compile it :
|
134
|
-
|
135
|
-
git clone git://github.com/etrepum/tokyo-cabinet.git
|
136
|
-
cd tokyo-cabinet
|
137
|
-
#git checkout 1.4.4
|
138
|
-
./configure
|
139
|
-
make
|
140
|
-
sudo make install
|
141
|
-
|
142
|
-
or get the souce at
|
143
|
-
|
144
|
-
http://sourceforge.net/project/showfiles.php?group_id=200242&package_id=237686
|
145
|
-
|
146
|
-
(note : I tend to run rufus-tokyo against the latest version of Tokyo Cabinet)
|
147
|
-
|
148
|
-
|
149
|
-
== Tokyo Tyrant install
|
150
|
-
|
151
|
-
(Tokyo Tyrant requires Tokyo Cabinet)
|
152
|
-
|
153
|
-
If you don't have Tokyo Tyrant on your system, you can get it and compile it :
|
154
|
-
|
155
|
-
git clone git://github.com/etrepum/tokyo-tyrant.git
|
156
|
-
cd tokyo-cabinet
|
157
|
-
#git checkout 1.1.14
|
158
|
-
./configure
|
159
|
-
make
|
160
|
-
sudo make install
|
195
|
+
== Tokyo Cabinet / Tyrant install
|
161
196
|
|
162
|
-
|
197
|
+
a compilation of notes is available at :
|
163
198
|
|
164
|
-
http://
|
199
|
+
http://openwferu.rubyforge.org/tokyo.html
|
165
200
|
|
166
201
|
|
167
202
|
== dependencies
|
168
203
|
|
169
|
-
|
204
|
+
the ruby gem 'ffi'
|
170
205
|
|
171
206
|
|
172
207
|
== mailing list
|
173
208
|
|
174
|
-
On the rufus-ruby list
|
209
|
+
On the rufus-ruby list :
|
175
210
|
|
176
211
|
http://groups.google.com/group/rufus-ruby
|
177
212
|
|
178
213
|
|
179
214
|
== issue tracker
|
180
215
|
|
181
|
-
http://rubyforge.org/tracker/?atid=18584&group_id=4812&func=browse
|
216
|
+
http://rubyforge.org/tracker/?atid=18584&group_id=4812&func=browse
|
182
217
|
|
183
218
|
|
184
219
|
== irc
|
data/lib/rufus/tokyo.rb
CHANGED
@@ -28,7 +28,7 @@ require 'ffi' # sudo gem install ffi
|
|
28
28
|
module Rufus
|
29
29
|
module Tokyo
|
30
30
|
|
31
|
-
VERSION = '0.1.
|
31
|
+
VERSION = '0.1.6'
|
32
32
|
|
33
33
|
#
|
34
34
|
# A common error class
|
@@ -38,8 +38,9 @@ module Rufus
|
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
|
-
require
|
42
|
-
|
43
|
-
|
44
|
-
require
|
41
|
+
require 'rufus/tokyo/cabinet'
|
42
|
+
|
43
|
+
# TODO : do not include me
|
44
|
+
#require 'rufus/tokyo/tyrant'
|
45
|
+
#require 'rufus/tokyo/dystopia'
|
45
46
|
|
data/lib/rufus/tokyo/cabinet.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
2
|
+
require 'rufus/tokyo/cabinet/lib'
|
3
|
+
require 'rufus/tokyo/cabinet/util'
|
4
|
+
require 'rufus/tokyo/cabinet/table'
|
5
|
+
require 'rufus/tokyo/cabinet/abstract'
|
6
6
|
|
@@ -35,23 +35,23 @@ module Rufus
|
|
35
35
|
# The libtokyocabinet.so methods get bound to this module
|
36
36
|
#
|
37
37
|
module CabinetLib #:nodoc#
|
38
|
-
extend
|
38
|
+
extend FFI::Library
|
39
39
|
|
40
40
|
#
|
41
41
|
# find Tokyo Cabinet lib
|
42
42
|
|
43
43
|
paths = Array(ENV['TOKYO_CABINET_LIB'] || %w{
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
44
|
+
/opt/local/lib/libtokyocabinet.dylib
|
45
|
+
/usr/local/lib/libtokyocabinet.dylib
|
46
|
+
/usr/local/lib/libtokyocabinet.so
|
47
|
+
})
|
48
48
|
|
49
49
|
path = paths.find { |path| File.exist?(path) }
|
50
50
|
|
51
51
|
raise(
|
52
|
-
|
53
|
-
|
54
|
-
|
52
|
+
"didn't find Tokyo Cabinet libs on your system. " +
|
53
|
+
"Please install Tokyo Cabinet (http://tokyocabinet.sf.net)"
|
54
|
+
) unless path
|
55
55
|
|
56
56
|
ffi_lib(path)
|
57
57
|
|
@@ -116,7 +116,9 @@ module Rufus
|
|
116
116
|
attfunc :tab_iternext2, :tctdbiternext2, [ :pointer ], :string
|
117
117
|
|
118
118
|
attfunc :tab_put, :tctdbput, [ :pointer, :string, :int, :pointer ], :int
|
119
|
-
|
119
|
+
|
120
|
+
#attfunc :tctdbput3, [ :pointer, :string, :string ], :int
|
121
|
+
# not using it anymore, Ruby can turn an array into a hash so easily
|
120
122
|
|
121
123
|
attfunc :tab_out, :tctdbout, [ :pointer, :string, :int ], :int
|
122
124
|
|
@@ -131,6 +133,10 @@ module Rufus
|
|
131
133
|
|
132
134
|
attfunc :tab_setindex, :tctdbsetindex, [ :pointer, :string, :int ], :int
|
133
135
|
|
136
|
+
attfunc :tctdbtranbegin, [ :pointer ], :int
|
137
|
+
attfunc :tctdbtrancommit, [ :pointer ], :int
|
138
|
+
attfunc :tctdbtranabort, [ :pointer ], :int
|
139
|
+
|
134
140
|
#
|
135
141
|
# tctdbqry functions
|
136
142
|
#
|
@@ -52,7 +52,7 @@ module Rufus
|
|
52
52
|
def params_to_h (params)
|
53
53
|
|
54
54
|
params.is_a?(Hash) ?
|
55
|
-
|
55
|
+
params :
|
56
56
|
Array(params).inject({}) { |h, e| h[e] = true; h }
|
57
57
|
end
|
58
58
|
|
@@ -146,7 +146,7 @@ module Rufus
|
|
146
146
|
|
147
147
|
@db = lib.tctdbnew
|
148
148
|
|
149
|
-
(
|
149
|
+
libcall(:tctdbopen, path, mode)
|
150
150
|
end
|
151
151
|
|
152
152
|
#
|
@@ -201,46 +201,21 @@ module Rufus
|
|
201
201
|
(lib.tab_setindex(@db, column_name, i) == 1)
|
202
202
|
end
|
203
203
|
|
204
|
-
#
|
205
|
-
# Accepts a variable number of arguments, at least two. First one
|
206
|
-
# is the primary key of the record, the others are the columns.
|
207
|
-
#
|
208
|
-
# One can also directly write
|
209
|
-
#
|
210
|
-
# table['one'] = [ 'name', 'toto', 'age', '33' ]
|
211
|
-
# table['two'] = [ 'name', 'fred', 'age', '45' ]
|
212
|
-
#
|
213
|
-
# instead of
|
214
|
-
#
|
215
|
-
# table.tabbed_put('one', 'name', 'toto', 'age', '33')
|
216
|
-
# table.tabbed_put('two', 'name', 'fred', 'age', '45')
|
217
|
-
#
|
218
|
-
# beware : inserting an array uses a tab separator...
|
219
|
-
#
|
220
|
-
def tabbed_put (pk, *args)
|
221
|
-
|
222
|
-
cols = args.collect { |e| e.to_s }.join("\t")
|
223
|
-
|
224
|
-
(CabinetLib.tctdbput3(@db, pk, cols) == 1) || raise_error
|
225
|
-
|
226
|
-
args
|
227
|
-
end
|
228
|
-
|
229
204
|
#
|
230
205
|
# Inserts a record in the table db
|
231
206
|
#
|
232
207
|
# table['pk0'] = [ 'name', 'fred', 'age', '45' ]
|
233
208
|
# table['pk1'] = { 'name' => 'jeff', 'age' => '46' }
|
234
209
|
#
|
210
|
+
# Accepts both a hash or an array (expects the array to be of the
|
211
|
+
# form [ key, value, key, value, ... ] else it will raise
|
212
|
+
# an ArgumentError)
|
213
|
+
#
|
235
214
|
def []= (pk, h_or_a)
|
236
215
|
|
237
|
-
|
238
|
-
|
239
|
-
pklen = CabinetLib.strlen(pk)
|
240
|
-
|
241
|
-
m = Map.from_h(h_or_a)
|
216
|
+
m = Rufus::Tokyo::Map[h_or_a]
|
242
217
|
|
243
|
-
r = lib.tab_put(@db, pk,
|
218
|
+
r = lib.tab_put(@db, pk, CabinetLib.strlen(pk), m.pointer)
|
244
219
|
|
245
220
|
m.free
|
246
221
|
|
@@ -258,7 +233,7 @@ module Rufus
|
|
258
233
|
def delete (k)
|
259
234
|
v = self[k]
|
260
235
|
return nil unless v
|
261
|
-
(
|
236
|
+
libcall(:tab_out, k, CabinetLib.strlen(k))
|
262
237
|
v
|
263
238
|
end
|
264
239
|
|
@@ -266,7 +241,7 @@ module Rufus
|
|
266
241
|
# Removes all records in this table database
|
267
242
|
#
|
268
243
|
def clear
|
269
|
-
(
|
244
|
+
libcall(:tab_vanish)
|
270
245
|
end
|
271
246
|
|
272
247
|
#
|
@@ -329,6 +304,70 @@ module Rufus
|
|
329
304
|
a
|
330
305
|
end
|
331
306
|
|
307
|
+
#
|
308
|
+
# Transaction in a block.
|
309
|
+
#
|
310
|
+
# table.transaction do
|
311
|
+
# table['pk0'] => { 'name' => 'Fred', 'age' => '40' }
|
312
|
+
# table['pk1'] => { 'name' => 'Brooke', 'age' => '76' }
|
313
|
+
# table.abort if weather.bad?
|
314
|
+
# end
|
315
|
+
#
|
316
|
+
# If an error or an abort is trigger withing the transaction, it's rolled
|
317
|
+
# back. If the block executes successfully, it gets commited.
|
318
|
+
#
|
319
|
+
def transaction
|
320
|
+
|
321
|
+
return unless block_given?
|
322
|
+
|
323
|
+
begin
|
324
|
+
tranbegin
|
325
|
+
yield
|
326
|
+
trancommit
|
327
|
+
rescue Exception => e
|
328
|
+
tranabort
|
329
|
+
end
|
330
|
+
end
|
331
|
+
|
332
|
+
#
|
333
|
+
# Aborts the enclosing transaction
|
334
|
+
#
|
335
|
+
# See #transaction
|
336
|
+
#
|
337
|
+
def abort
|
338
|
+
raise "abort transaction !"
|
339
|
+
end
|
340
|
+
|
341
|
+
#
|
342
|
+
# Warning : this method is low-level, you probably only need
|
343
|
+
# to use #transaction and a block.
|
344
|
+
#
|
345
|
+
# Direct call for 'transaction begin'.
|
346
|
+
#
|
347
|
+
def tranbegin
|
348
|
+
libcall(:tctdbtranbegin)
|
349
|
+
end
|
350
|
+
|
351
|
+
#
|
352
|
+
# Warning : this method is low-level, you probably only need
|
353
|
+
# to use #transaction and a block.
|
354
|
+
#
|
355
|
+
# Direct call for 'transaction commit'.
|
356
|
+
#
|
357
|
+
def trancommit
|
358
|
+
libcall(:tctdbtrancommit)
|
359
|
+
end
|
360
|
+
|
361
|
+
#
|
362
|
+
# Warning : this method is low-level, you probably only need
|
363
|
+
# to use #transaction and a block.
|
364
|
+
#
|
365
|
+
# Direct call for 'transaction abort'.
|
366
|
+
#
|
367
|
+
def tranabort
|
368
|
+
libcall(:tctdbtranabort)
|
369
|
+
end
|
370
|
+
|
332
371
|
#
|
333
372
|
# Returns the actual pointer to the Tokyo Cabinet table
|
334
373
|
#
|
@@ -338,6 +377,15 @@ module Rufus
|
|
338
377
|
|
339
378
|
protected
|
340
379
|
|
380
|
+
def libcall (lib_method, *args)
|
381
|
+
|
382
|
+
#(lib.send(lib_method, @db, *args) == 1) or raise_error
|
383
|
+
# stack level too deep with JRuby 1.1.6 :(
|
384
|
+
|
385
|
+
(eval(%{ lib.#{lib_method}(@db, *args) }) == 1) or raise_error
|
386
|
+
# works with JRuby 1.1.6
|
387
|
+
end
|
388
|
+
|
341
389
|
#
|
342
390
|
# Obviously something got wrong, let's ask the db about it and raise
|
343
391
|
# a TokyoError
|
@@ -28,6 +28,9 @@
|
|
28
28
|
# jmettraux@gmail.com
|
29
29
|
#
|
30
30
|
|
31
|
+
require 'rufus/tokyo/hmethods'
|
32
|
+
|
33
|
+
|
31
34
|
module Rufus
|
32
35
|
module Tokyo
|
33
36
|
|
@@ -142,10 +145,24 @@ module Rufus
|
|
142
145
|
|
143
146
|
#
|
144
147
|
# Turns a Ruby hash into a Tokyo Cabinet Map and returns it
|
148
|
+
# (don't forget to free the map when you're done with it !)
|
145
149
|
#
|
146
150
|
def self.from_h (h)
|
147
151
|
h.inject(Map.new) { |m, (k, v)| m[k] = v; m }
|
148
152
|
end
|
153
|
+
|
154
|
+
#
|
155
|
+
# Behaves much like Hash#[] but outputs a Rufus::Tokyo::Map
|
156
|
+
# (don't forget to free the map when you're done with it !)
|
157
|
+
#
|
158
|
+
def self.[] (*h_or_a)
|
159
|
+
|
160
|
+
if h_or_a.is_a?(Array) && h_or_a.size == 1 && h_or_a.first.is_a?(Array)
|
161
|
+
h_or_a = h_or_a.first
|
162
|
+
end
|
163
|
+
|
164
|
+
from_h(::Hash[*h_or_a])
|
165
|
+
end
|
149
166
|
end
|
150
167
|
|
151
168
|
#
|
@@ -173,8 +190,11 @@ module Rufus
|
|
173
190
|
CabinetLib
|
174
191
|
end
|
175
192
|
|
193
|
+
#
|
194
|
+
# Inserts an element in the list (note that the lib will raise an
|
195
|
+
# ArgumentError if s is not a String)
|
196
|
+
#
|
176
197
|
def << (s)
|
177
|
-
#raise 'cannot insert nils into Tokyo Cabinet lists' unless s
|
178
198
|
clib.tclistpush2(@list, s)
|
179
199
|
self
|
180
200
|
end
|
@@ -184,6 +204,7 @@ module Rufus
|
|
184
204
|
#
|
185
205
|
def push (*args)
|
186
206
|
args.each { |a| self << a }
|
207
|
+
self
|
187
208
|
end
|
188
209
|
|
189
210
|
#
|
data/lib/rufus/tokyo/dystopia.rb
CHANGED
@@ -36,41 +36,36 @@ module Rufus
|
|
36
36
|
#
|
37
37
|
module DystopiaLib #:nodoc#
|
38
38
|
|
39
|
+
extend FFI::Library
|
40
|
+
|
39
41
|
#
|
40
42
|
# find Tokyo Dystopia lib
|
41
43
|
|
42
44
|
paths = Array(ENV['TOKYO_DYSTOPIA_LIB'] || %w{
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
45
|
+
/opt/local/lib/libtokyodystopia.dylib
|
46
|
+
/usr/local/lib/libtokyodystopia.dylib
|
47
|
+
/usr/local/lib/libtokyodystopia.so
|
48
|
+
})
|
47
49
|
|
48
50
|
if path = paths.find { |path| File.exist?(path) }
|
49
51
|
|
50
|
-
|
51
|
-
|
52
|
-
ffi_lib(path)
|
52
|
+
raise "did not find Tokyo Dystopia libs on your system" unless path
|
53
53
|
|
54
|
-
|
55
|
-
# tcwdb functions
|
56
|
-
#
|
57
|
-
# http://tokyocabinet.sourceforge.net/dystopiadoc/#tcwdbapi
|
54
|
+
ffi_lib(path)
|
58
55
|
|
59
|
-
|
56
|
+
#
|
57
|
+
# tcwdb functions
|
58
|
+
#
|
59
|
+
# http://tokyocabinet.sourceforge.net/dystopiadoc/#tcwdbapi
|
60
60
|
|
61
|
-
|
62
|
-
attach_function :tcwdbclose, [ :pointer ], :int
|
61
|
+
attach_function :tcwdbnew, [], :pointer
|
63
62
|
|
64
|
-
|
63
|
+
attach_function :tcwdbopen, [ :pointer, :string, :int ], :int
|
64
|
+
attach_function :tcwdbclose, [ :pointer ], :int
|
65
65
|
|
66
|
-
|
67
|
-
else
|
66
|
+
attach_function :tcwdbecode, [ :pointer ], :int
|
68
67
|
|
69
|
-
|
70
|
-
raise "no libtokyodystopia.dylib found on your system"
|
71
|
-
end
|
72
|
-
end
|
68
|
+
attach_function :tcwdbput2, [ :pointer, :int64, :string, :string ], :pointer
|
73
69
|
end
|
74
|
-
|
75
70
|
end
|
76
71
|
end
|
data/lib/rufus/tokyo/tyrant.rb
CHANGED
@@ -1,5 +1,58 @@
|
|
1
|
+
#
|
2
|
+
#--
|
3
|
+
# Copyright (c) 2009, John Mettraux, jmettraux@gmail.com
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
13
|
+
# all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
# THE SOFTWARE.
|
22
|
+
#++
|
23
|
+
#
|
1
24
|
|
2
|
-
|
3
|
-
|
4
|
-
|
25
|
+
#
|
26
|
+
# "made in Japan"
|
27
|
+
#
|
28
|
+
# jmettraux@gmail.com
|
29
|
+
#
|
30
|
+
|
31
|
+
require 'rufus/tokyo'
|
32
|
+
|
33
|
+
module Rufus::Tokyo
|
34
|
+
|
35
|
+
#
|
36
|
+
# Gathering some methods common to the Tokyo Tyrant abstract and table APIs.
|
37
|
+
#
|
38
|
+
module TyrantMethods
|
39
|
+
|
40
|
+
#
|
41
|
+
# Returns a hash of information about the Tokyo Tyrant database (or table)
|
42
|
+
# at the other end of the connection.
|
43
|
+
#
|
44
|
+
def stat
|
45
|
+
|
46
|
+
lib.tcrdbstat(@db).split("\n").inject({}) { |r, l|
|
47
|
+
kv = l.split("\t")
|
48
|
+
r[kv.first] = kv.last
|
49
|
+
r
|
50
|
+
}
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
require 'rufus/tokyo/tyrant/lib'
|
56
|
+
require 'rufus/tokyo/tyrant/abstract'
|
57
|
+
require 'rufus/tokyo/tyrant/table'
|
5
58
|
|
@@ -40,6 +40,7 @@ module Rufus
|
|
40
40
|
# t['toto'] # => 'blah blah'
|
41
41
|
#
|
42
42
|
class Tyrant < Cabinet
|
43
|
+
include TyrantMethods
|
43
44
|
|
44
45
|
attr_reader :host, :port
|
45
46
|
|
@@ -55,6 +56,15 @@ module Rufus
|
|
55
56
|
|
56
57
|
(lib.tcrdbopen(@db, host, port) == 1) ||
|
57
58
|
raise("couldn't connect to tyrant at #{host}:#{port}")
|
59
|
+
|
60
|
+
if self.stat['type'] == 'table'
|
61
|
+
|
62
|
+
self.close
|
63
|
+
|
64
|
+
raise ArgumentError.new(
|
65
|
+
"tyrant at #{host}:#{port} is a table, " +
|
66
|
+
"use Rufus::Tokyo::TyrantTable instead to access it.")
|
67
|
+
end
|
58
68
|
end
|
59
69
|
|
60
70
|
#
|
@@ -64,6 +74,5 @@ module Rufus
|
|
64
74
|
TyrantLib
|
65
75
|
end
|
66
76
|
end
|
67
|
-
|
68
77
|
end
|
69
78
|
end
|
@@ -36,97 +36,92 @@ module Rufus
|
|
36
36
|
#
|
37
37
|
module TyrantLib #:nodoc#
|
38
38
|
|
39
|
+
extend FFI::Library
|
40
|
+
|
39
41
|
#
|
40
42
|
# find Tokyo Tyrant lib
|
41
43
|
|
42
44
|
paths = Array(ENV['TOKYO_TYRANT_LIB'] || %w{
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
if path = paths.find { |path| File.exist?(path) }
|
49
|
-
|
50
|
-
extend ::FFI::Library
|
45
|
+
/opt/local/lib/libtokyotyrant.dylib
|
46
|
+
/usr/local/lib/libtokyotyrant.dylib
|
47
|
+
/usr/local/lib/libtokyotyrant.so
|
48
|
+
})
|
51
49
|
|
52
|
-
|
50
|
+
path = paths.find { |path| File.exist?(path) }
|
53
51
|
|
54
|
-
|
55
|
-
alias :attfunc :attach_function
|
56
|
-
end
|
52
|
+
raise "Did not find Tokyo Tyrant libraries on your system" unless path
|
57
53
|
|
58
|
-
|
59
|
-
# tcrdb functions
|
54
|
+
ffi_lib(path)
|
60
55
|
|
61
|
-
|
56
|
+
class << self
|
57
|
+
alias :attfunc :attach_function
|
58
|
+
end
|
62
59
|
|
63
|
-
|
64
|
-
|
60
|
+
#
|
61
|
+
# tcrdb functions
|
65
62
|
|
66
|
-
|
63
|
+
attfunc :tcrdbnew, [], :pointer
|
67
64
|
|
68
|
-
|
69
|
-
attfunc :abs_size, :tcrdbsize, [ :pointer ], :uint64
|
65
|
+
attfunc :tcrdbstat, [ :pointer ], :string
|
70
66
|
|
71
|
-
|
72
|
-
|
73
|
-
attfunc :abs_out2, :tcrdbout2, [ :pointer, :string ], :int
|
67
|
+
attfunc :tcrdbopen, [ :pointer, :string, :int ], :int
|
68
|
+
attfunc :abs_close, :tcrdbclose, [ :pointer ], :int
|
74
69
|
|
75
|
-
|
76
|
-
attfunc :abs_iternext2, :tcrdbiternext2, [ :pointer ], :string
|
70
|
+
attfunc :abs_del, :tcrdbdel, [ :pointer ], :void
|
77
71
|
|
78
|
-
|
72
|
+
attfunc :abs_rnum, :tcrdbrnum, [ :pointer ], :uint64
|
73
|
+
attfunc :abs_size, :tcrdbsize, [ :pointer ], :uint64
|
79
74
|
|
80
|
-
|
81
|
-
|
75
|
+
attfunc :abs_put2, :tcrdbput2, [ :pointer, :string, :string ], :int
|
76
|
+
attfunc :abs_get2, :tcrdbget2, [ :pointer, :string ], :string
|
77
|
+
attfunc :abs_out2, :tcrdbout2, [ :pointer, :string ], :int
|
82
78
|
|
83
|
-
|
84
|
-
|
79
|
+
attfunc :abs_iterinit, :tcrdbiterinit, [ :pointer ], :int
|
80
|
+
attfunc :abs_iternext2, :tcrdbiternext2, [ :pointer ], :string
|
85
81
|
|
86
|
-
|
82
|
+
attfunc :abs_vanish, :tcrdbvanish, [ :pointer ], :int
|
87
83
|
|
88
|
-
|
84
|
+
attfunc :abs_sync, :tcrdbsync, [ :pointer ], :int
|
85
|
+
attfunc :abs_copy, :tcrdbcopy, [ :pointer, :string ], :int
|
89
86
|
|
90
|
-
|
87
|
+
#
|
88
|
+
# table functions
|
91
89
|
|
92
|
-
|
93
|
-
attfunc :tab_iternext2, :tcrdbiternext2, [ :pointer ], :string
|
90
|
+
attfunc :tab_close, :tcrdbclose, [ :pointer ], :int
|
94
91
|
|
95
|
-
|
92
|
+
attfunc :tab_genuid, :tcrdbtblgenuid, [ :pointer ], :int64
|
96
93
|
|
97
|
-
|
94
|
+
attfunc :tab_get, :tcrdbtblget, [ :pointer, :string, :int ], :pointer
|
98
95
|
|
99
|
-
|
100
|
-
|
96
|
+
attfunc :tab_iterinit, :tcrdbiterinit, [ :pointer ], :int
|
97
|
+
attfunc :tab_iternext2, :tcrdbiternext2, [ :pointer ], :string
|
101
98
|
|
102
|
-
|
99
|
+
attfunc :tab_put, :tcrdbtblput, [ :pointer, :string, :int, :pointer ], :int
|
103
100
|
|
104
|
-
|
101
|
+
attfunc :tab_out, :tcrdbtblout, [ :pointer, :string, :int ], :int
|
105
102
|
|
106
|
-
|
103
|
+
attfunc :tab_ecode, :tcrdbecode, [ :pointer ], :int
|
104
|
+
attfunc :tab_errmsg, :tcrdberrmsg, [ :int ], :string
|
107
105
|
|
108
|
-
|
106
|
+
attfunc :tab_del, :tcrdbdel, [ :pointer ], :void
|
109
107
|
|
110
|
-
|
111
|
-
# qry functions
|
108
|
+
attfunc :tab_rnum, :tcrdbrnum, [ :pointer ], :uint64
|
112
109
|
|
113
|
-
|
114
|
-
attfunc :qry_del, :tcrdbqrydel, [ :pointer ], :void
|
110
|
+
attfunc :tab_vanish, :tcrdbvanish, [ :pointer ], :int
|
115
111
|
|
116
|
-
|
117
|
-
attfunc :qry_setorder, :tcrdbqrysetorder, [ :pointer, :string, :int ], :void
|
118
|
-
attfunc :qry_setmax, :tcrdbqrysetmax, [ :pointer, :int ], :void
|
112
|
+
attfunc :tab_setindex, :tcrdbtblsetindex, [ :pointer, :string, :int ], :int
|
119
113
|
|
120
|
-
|
114
|
+
#
|
115
|
+
# qry functions
|
121
116
|
|
122
|
-
|
117
|
+
attfunc :qry_new, :tcrdbqrynew, [ :pointer ], :pointer
|
118
|
+
attfunc :qry_del, :tcrdbqrydel, [ :pointer ], :void
|
123
119
|
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
end
|
120
|
+
attfunc :qry_addcond, :tcrdbqryaddcond, [ :pointer, :string, :int, :string ], :void
|
121
|
+
attfunc :qry_setorder, :tcrdbqrysetorder, [ :pointer, :string, :int ], :void
|
122
|
+
attfunc :qry_setmax, :tcrdbqrysetmax, [ :pointer, :int ], :void
|
128
123
|
|
124
|
+
attfunc :qry_search, :tcrdbqrysearch, [ :pointer ], :pointer
|
129
125
|
end
|
130
|
-
|
131
126
|
end
|
132
127
|
end
|
@@ -41,6 +41,7 @@ module Rufus
|
|
41
41
|
# # => { 'name' => 'toto the first', 'age' => '34' }
|
42
42
|
#
|
43
43
|
class TyrantTable < Table
|
44
|
+
include TyrantMethods
|
44
45
|
|
45
46
|
attr_reader :host, :port
|
46
47
|
|
@@ -53,6 +54,15 @@ module Rufus
|
|
53
54
|
|
54
55
|
(lib.tcrdbopen(@db, host, port) == 1) ||
|
55
56
|
raise("couldn't connect to tyrant at #{host}:#{port}")
|
57
|
+
|
58
|
+
if self.stat['type'] != 'table'
|
59
|
+
|
60
|
+
self.close
|
61
|
+
|
62
|
+
raise ArgumentError.new(
|
63
|
+
"tyrant at #{host}:#{port} is a not table, " +
|
64
|
+
"use Rufus::Tokyo::Tyrant instead to access it.")
|
65
|
+
end
|
56
66
|
end
|
57
67
|
|
58
68
|
#
|
@@ -62,24 +72,27 @@ module Rufus
|
|
62
72
|
TyrantLib
|
63
73
|
end
|
64
74
|
|
65
|
-
#
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
75
|
+
def transaction #:nodoc#
|
76
|
+
raise_transaction_nme('transaction')
|
77
|
+
end
|
78
|
+
def abort #:nodoc#
|
79
|
+
raise_transaction_nme('abort')
|
80
|
+
end
|
81
|
+
def tranbegin #:nodoc#
|
82
|
+
raise_transaction_nme('tranbegin')
|
83
|
+
end
|
84
|
+
def trancommit #:nodoc#
|
85
|
+
raise_transaction_nme('trancommit')
|
86
|
+
end
|
87
|
+
def tranabort #:nodoc#
|
88
|
+
raise_transaction_nme('tranabort')
|
89
|
+
end
|
79
90
|
|
80
|
-
|
91
|
+
protected
|
81
92
|
|
82
|
-
|
93
|
+
def raise_transaction_nme (method_name)
|
94
|
+
raise NoMethodError.new(
|
95
|
+
"Tyrant tables don't support transactions", method_name)
|
83
96
|
end
|
84
97
|
end
|
85
98
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rufus-tokyo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Mettraux
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2009-02-
|
13
|
+
date: 2009-02-16 00:00:00 +09:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|