redisk 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -1
- data/HISTORY +14 -0
- data/README.rdoc +18 -0
- data/examples/rails.rb +4 -0
- data/examples/yajl.rb +24 -0
- data/lib/redisk/io.rb +215 -39
- data/lib/redisk.rb +18 -1
- data/redisk.gemspec +8 -3
- data/spec/redisk_io_spec.rb +291 -25
- metadata +7 -2
data/.gitignore
CHANGED
data/HISTORY
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
=== 0.2.0 [2009-12-22]
|
2
|
+
|
3
|
+
* Almost complete support for both line and byte operations on Redisk::IO
|
4
|
+
* New special extensions to the base IO class:
|
5
|
+
* .from_file and .to_file for writing/reading to disk
|
6
|
+
* .unlink for deleting contents
|
7
|
+
* .all lists the IO's created by Redisk::IO
|
8
|
+
* New examples folder
|
9
|
+
|
10
|
+
=== 0.1.0
|
11
|
+
|
12
|
+
* Initial Release.
|
13
|
+
* Basic support for line operations in Redisk::IO
|
14
|
+
* Redisk::Logger
|
data/README.rdoc
CHANGED
@@ -41,6 +41,24 @@ By default, Redisk uses the Redis on localhost:6379, but you can change that by
|
|
41
41
|
|
42
42
|
Redisk.redis = 'myhost:myport'
|
43
43
|
|
44
|
+
Check out the small but growing list of examples in examples/
|
45
|
+
|
46
|
+
== INSTALL (NOW!)
|
47
|
+
|
48
|
+
Proudly tested and working on Ruby 1.8.6, 1.8.7, and 1.9.1
|
49
|
+
|
50
|
+
Gems are on gemcutter:
|
51
|
+
|
52
|
+
gem install redisk
|
53
|
+
|
54
|
+
Dependencies:
|
55
|
+
|
56
|
+
redis running somewhere
|
57
|
+
|
58
|
+
gems:
|
59
|
+
redis
|
60
|
+
redis-namespace
|
61
|
+
|
44
62
|
== Note on Patches/Pull Requests
|
45
63
|
|
46
64
|
* Fork the project.
|
data/examples/rails.rb
ADDED
data/examples/yajl.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'yajl'
|
3
|
+
require 'redisk'
|
4
|
+
|
5
|
+
hash = {'something' => 'for nothing', 'and_the_rest' => 'for free', 'i' => {'want' => {'my' => 'mtv'}}}
|
6
|
+
|
7
|
+
io_name = 'test.json'
|
8
|
+
Redisk::IO.unlink(io_name)
|
9
|
+
|
10
|
+
puts 'The hash:'
|
11
|
+
puts hash.inspect
|
12
|
+
|
13
|
+
puts 'write the hash as json to redis'
|
14
|
+
io = Redisk::IO.new(io_name)
|
15
|
+
Yajl::Encoder.encode(hash, io)
|
16
|
+
|
17
|
+
puts 'read it back out'
|
18
|
+
io.rewind
|
19
|
+
puts io.read.inspect
|
20
|
+
|
21
|
+
io.rewind
|
22
|
+
|
23
|
+
puts 'parse it back to ruby'
|
24
|
+
puts Yajl::Parser.parse(io).inspect
|
data/lib/redisk/io.rb
CHANGED
@@ -6,16 +6,24 @@ module Redisk
|
|
6
6
|
|
7
7
|
class NotImplementedError < RuntimeError; end
|
8
8
|
class EOFError < ::EOFError; end
|
9
|
+
class IOError < ::IOError; end
|
9
10
|
|
10
11
|
attr_reader :name, :mode, :_
|
11
12
|
|
12
|
-
def initialize(name, mode = '
|
13
|
-
@name
|
14
|
-
@mode
|
15
|
-
@
|
16
|
-
@
|
17
|
-
@
|
18
|
-
@
|
13
|
+
def initialize(name, mode = 'r')
|
14
|
+
@name = name
|
15
|
+
@mode = mode # we're going to just ignore this for now
|
16
|
+
@read_open = true
|
17
|
+
@write_open = true
|
18
|
+
@write_buffer = nil
|
19
|
+
@read_buffer = nil
|
20
|
+
@sync = false
|
21
|
+
@pos = 0
|
22
|
+
@lineno = 0
|
23
|
+
@size = stat.size > 0 ? stat.size : true_size
|
24
|
+
# add io to the list of ios
|
25
|
+
redis.sadd dir, name
|
26
|
+
rewind
|
19
27
|
end
|
20
28
|
alias :for_fd :initialize
|
21
29
|
|
@@ -26,7 +34,19 @@ module Redisk
|
|
26
34
|
def list_key
|
27
35
|
self.class.list_key(name)
|
28
36
|
end
|
37
|
+
|
38
|
+
def self.all
|
39
|
+
redis.smembers dir
|
40
|
+
end
|
29
41
|
|
42
|
+
def self.dir
|
43
|
+
"__ios__"
|
44
|
+
end
|
45
|
+
|
46
|
+
def dir
|
47
|
+
self.class.dir
|
48
|
+
end
|
49
|
+
|
30
50
|
# Executes the block for every line in the named I/O port, where lines are
|
31
51
|
# separated by sep_string.
|
32
52
|
#
|
@@ -38,8 +58,9 @@ module Redisk
|
|
38
58
|
# GOT This is line three
|
39
59
|
# GOT And so on...
|
40
60
|
def self.foreach(name, &block)
|
41
|
-
|
42
|
-
|
61
|
+
io = new(name)
|
62
|
+
io.each_line(&block)
|
63
|
+
io.close
|
43
64
|
end
|
44
65
|
|
45
66
|
# With no associated block, open is a synonym for IO::new. If the optional
|
@@ -48,7 +69,9 @@ module Redisk
|
|
48
69
|
# instance, IO::open returns the value of the block.
|
49
70
|
def self.open(name, mode = 'r')
|
50
71
|
io = new(name, mode)
|
51
|
-
block_given? ? yield(io) : io
|
72
|
+
returned = block_given? ? yield(io) : io
|
73
|
+
io.close
|
74
|
+
returned
|
52
75
|
end
|
53
76
|
|
54
77
|
# IO.pipe → array
|
@@ -92,12 +115,21 @@ module Redisk
|
|
92
115
|
# IO.read("testfile", 20) #=> "This is line one\nThi"
|
93
116
|
# IO.read("testfile", 20, 10) #=> "ne one\nThis is line "
|
94
117
|
def self.read(name, length = nil, offset = nil)
|
118
|
+
io = new(name)
|
119
|
+
io.seek(offset) if offset
|
120
|
+
returned = io.read(length)
|
121
|
+
io.close
|
122
|
+
returned
|
123
|
+
end
|
124
|
+
|
125
|
+
# Works similarly to IO.read, but operates on lines instead of bytes
|
126
|
+
def self.read_lines(name, length = nil, offset = nil)
|
95
127
|
start_i = offset || 0
|
96
128
|
end_i = length ? start_i + (length - 1) : -1
|
97
129
|
values = redis.lrange(list_key(name), start_i, end_i)
|
98
|
-
values.join
|
130
|
+
values.join
|
99
131
|
end
|
100
|
-
|
132
|
+
|
101
133
|
# Reads the entire file specified by name as individual lines, and returns
|
102
134
|
# those lines in an array. Lines are separated by sep_string.
|
103
135
|
#
|
@@ -125,6 +157,31 @@ module Redisk
|
|
125
157
|
raise NotImplementedError, ".sysopen is not implemented"
|
126
158
|
end
|
127
159
|
|
160
|
+
# Removes all references to the io at name
|
161
|
+
def self.unlink(name)
|
162
|
+
redis.keys("#{name}:*").each do |key|
|
163
|
+
redis.del key.gsub('redisk:','')
|
164
|
+
end
|
165
|
+
redis.srem dir, name
|
166
|
+
nil
|
167
|
+
end
|
168
|
+
|
169
|
+
# Reads the contents of file into the IO.
|
170
|
+
# If file is not a File its taken as a path and passed to File.open
|
171
|
+
def self.from_file(name, file)
|
172
|
+
io = new(name)
|
173
|
+
io.from_file(file)
|
174
|
+
io
|
175
|
+
end
|
176
|
+
|
177
|
+
# Writes the contents of IO into file.
|
178
|
+
# If file is not a File its taken as a path and passed to File.open
|
179
|
+
def self.to_file(name, file)
|
180
|
+
io = new(name)
|
181
|
+
io.to_file(file)
|
182
|
+
io
|
183
|
+
end
|
184
|
+
|
128
185
|
# String Output—Writes obj to ios. obj will be converted to a string using
|
129
186
|
# to_s.
|
130
187
|
#
|
@@ -133,10 +190,10 @@ module Redisk
|
|
133
190
|
#
|
134
191
|
# Hello world!
|
135
192
|
def <<(text)
|
136
|
-
@
|
137
|
-
@
|
193
|
+
@write_buffer ||= ''
|
194
|
+
@write_buffer << text
|
138
195
|
flush if sync
|
139
|
-
@
|
196
|
+
@write_buffer
|
140
197
|
end
|
141
198
|
|
142
199
|
# ios.binmode => ios
|
@@ -154,7 +211,9 @@ module Redisk
|
|
154
211
|
#
|
155
212
|
# If ios is opened by IO.popen, close sets $?.
|
156
213
|
def close
|
157
|
-
|
214
|
+
flush
|
215
|
+
close_read
|
216
|
+
close_write
|
158
217
|
end
|
159
218
|
|
160
219
|
# ios.close_read => nil
|
@@ -170,7 +229,8 @@ module Redisk
|
|
170
229
|
# prog.rb:3:in `readlines': not opened for reading (IOError)
|
171
230
|
# from prog.rb:3
|
172
231
|
def close_read
|
173
|
-
|
232
|
+
@read_open = false
|
233
|
+
nil
|
174
234
|
end
|
175
235
|
|
176
236
|
# ios.close_write => nil
|
@@ -187,7 +247,8 @@ module Redisk
|
|
187
247
|
# from prog.rb:3:in `print'
|
188
248
|
# from prog.rb:3
|
189
249
|
def close_write
|
190
|
-
|
250
|
+
@write_open = false
|
251
|
+
nil
|
191
252
|
end
|
192
253
|
|
193
254
|
# ios.closed? => true or false
|
@@ -202,8 +263,8 @@ module Redisk
|
|
202
263
|
# f.closed? #=> false
|
203
264
|
# f.close_read #=> nil
|
204
265
|
# f.closed? #=> true
|
205
|
-
def closed
|
206
|
-
|
266
|
+
def closed?
|
267
|
+
!(@write_open || @read_open)
|
207
268
|
end
|
208
269
|
|
209
270
|
# ios.each(sep_string=$/) {|line| block } => ios
|
@@ -238,7 +299,11 @@ module Redisk
|
|
238
299
|
# f.each_byte {|x| checksum ^= x } #=> #<File:testfile>
|
239
300
|
# checksum #=> 12
|
240
301
|
def each_byte
|
241
|
-
|
302
|
+
rewind
|
303
|
+
while !eof?
|
304
|
+
yield getc
|
305
|
+
end
|
306
|
+
self
|
242
307
|
end
|
243
308
|
|
244
309
|
# ios.eof => true or false
|
@@ -266,7 +331,7 @@ module Redisk
|
|
266
331
|
# Note that IO#eof? reads data to a input buffer. So IO#sysread doesn‘t
|
267
332
|
# work with IO#eof?.
|
268
333
|
def eof
|
269
|
-
lineno >= length
|
334
|
+
lineno >= length || pos >= size
|
270
335
|
end
|
271
336
|
alias :eof? :eof
|
272
337
|
|
@@ -302,13 +367,13 @@ module Redisk
|
|
302
367
|
#
|
303
368
|
# no newline
|
304
369
|
def flush
|
305
|
-
if @
|
306
|
-
redis.rpush list_key, @
|
307
|
-
@size += @
|
370
|
+
if @write_buffer && @write_buffer != ''
|
371
|
+
redis.rpush list_key, @write_buffer
|
372
|
+
@size += @write_buffer.length
|
308
373
|
stat.write_attribute(:size, @size)
|
309
374
|
stat.write_attribute(:mtime, Time.now)
|
310
375
|
end
|
311
|
-
@
|
376
|
+
@write_buffer = nil
|
312
377
|
end
|
313
378
|
|
314
379
|
# ios.fsync => 0 or nil
|
@@ -318,6 +383,31 @@ module Redisk
|
|
318
383
|
# from Ruby‘s buffers, but doesn‘t not guarantee that the underlying
|
319
384
|
# operating system actually writes it to disk.
|
320
385
|
def fsync
|
386
|
+
false
|
387
|
+
end
|
388
|
+
|
389
|
+
# Reads the contents of file into the IO.
|
390
|
+
# If file is not a File its taken as a path and passed to File.open
|
391
|
+
# Returns the IO
|
392
|
+
def from_file(file)
|
393
|
+
file = File.open(file, 'r') if !file.is_a?(File)
|
394
|
+
file.each_line do |l|
|
395
|
+
write l
|
396
|
+
end
|
397
|
+
file.close
|
398
|
+
self
|
399
|
+
end
|
400
|
+
|
401
|
+
# Writes the contents of IO into file.
|
402
|
+
# If file is not a File its taken as a path and passed to File.open
|
403
|
+
# Returns the IO
|
404
|
+
def to_file(file)
|
405
|
+
file = File.open(file, 'w') if !file.is_a?(File)
|
406
|
+
each_line do |l|
|
407
|
+
file.write l
|
408
|
+
end
|
409
|
+
file.close
|
410
|
+
self
|
321
411
|
end
|
322
412
|
|
323
413
|
# ios.getc => fixnum or nil
|
@@ -328,6 +418,7 @@ module Redisk
|
|
328
418
|
# f.getc #=> 84
|
329
419
|
# f.getc #=> 104
|
330
420
|
def getc
|
421
|
+
read(1).to_s.ord
|
331
422
|
end
|
332
423
|
|
333
424
|
# ios.gets(sep_string=$/) => string or nil
|
@@ -342,11 +433,14 @@ module Redisk
|
|
342
433
|
# File.new("testfile").gets #=> "This is line one\n"
|
343
434
|
# $_ #=> "This is line one\n"
|
344
435
|
def gets
|
436
|
+
check_stream_open!(:read)
|
345
437
|
flush
|
438
|
+
return nil if eof?
|
346
439
|
val = redis.lrange(list_key, lineno, lineno + 1)
|
347
440
|
if val = val.first
|
348
441
|
self.lineno += 1
|
349
442
|
$_ = @_ = val
|
443
|
+
@pos += val.length
|
350
444
|
val
|
351
445
|
end
|
352
446
|
end
|
@@ -387,6 +481,10 @@ module Redisk
|
|
387
481
|
@size
|
388
482
|
end
|
389
483
|
|
484
|
+
def true_size
|
485
|
+
readlines.join.length
|
486
|
+
end
|
487
|
+
|
390
488
|
# ios.lineno => integer
|
391
489
|
# Returns the current line number in ios. The stream must be opened for
|
392
490
|
# reading. lineno counts the number of times gets is called, rather than
|
@@ -416,7 +514,15 @@ module Redisk
|
|
416
514
|
# f.gets #=> "This is line two\n"
|
417
515
|
# $. # lineno of last read #=> 1001
|
418
516
|
def lineno=(num)
|
419
|
-
@lineno = num
|
517
|
+
@lineno = num.to_i
|
518
|
+
end
|
519
|
+
|
520
|
+
def open?(stream = nil)
|
521
|
+
if stream
|
522
|
+
instance_variable_get("@#{stream}_open")
|
523
|
+
else
|
524
|
+
@write_open && @read_open
|
525
|
+
end
|
420
526
|
end
|
421
527
|
|
422
528
|
# ios.pid => fixnum
|
@@ -434,7 +540,7 @@ module Redisk
|
|
434
540
|
# In child, pid is 26209
|
435
541
|
# In parent, child pid is 26209
|
436
542
|
def pid
|
437
|
-
|
543
|
+
Process.pid
|
438
544
|
end
|
439
545
|
|
440
546
|
# ios.pos => integer
|
@@ -446,7 +552,7 @@ module Redisk
|
|
446
552
|
# f.gets #=> "This is line one\n"
|
447
553
|
# f.pos #=> 17
|
448
554
|
def pos
|
449
|
-
|
555
|
+
@pos
|
450
556
|
end
|
451
557
|
alias :tell :pos
|
452
558
|
|
@@ -457,7 +563,13 @@ module Redisk
|
|
457
563
|
# f.pos = 17
|
458
564
|
# f.gets #=> "This is line two\n"
|
459
565
|
def pos=(num)
|
460
|
-
|
566
|
+
current_pos = @pos
|
567
|
+
if num < current_pos
|
568
|
+
@pos = 0
|
569
|
+
else
|
570
|
+
num -= current_pos
|
571
|
+
end
|
572
|
+
read(num)
|
461
573
|
end
|
462
574
|
|
463
575
|
# ios.print() => nil
|
@@ -497,7 +609,7 @@ module Redisk
|
|
497
609
|
#
|
498
610
|
# AA
|
499
611
|
def putc(obj)
|
500
|
-
|
612
|
+
self << obj.is_a?(Fixnum) ? obj : obj.to_s[0]
|
501
613
|
end
|
502
614
|
|
503
615
|
# ios.puts(obj, ...) => nil
|
@@ -516,8 +628,11 @@ module Redisk
|
|
516
628
|
# test
|
517
629
|
def puts(*args)
|
518
630
|
args.empty? ?
|
519
|
-
write(
|
520
|
-
args.each {|a|
|
631
|
+
write("\n") :
|
632
|
+
args.each {|a|
|
633
|
+
a += "\n" if a !~ /\n$/
|
634
|
+
write(a)
|
635
|
+
}
|
521
636
|
nil
|
522
637
|
end
|
523
638
|
|
@@ -532,8 +647,30 @@ module Redisk
|
|
532
647
|
#
|
533
648
|
# f = File.new("testfile")
|
534
649
|
# f.read(16) #=> "This is line one"
|
535
|
-
def read
|
536
|
-
|
650
|
+
def read(length = nil, buffer = nil)
|
651
|
+
check_stream_open!(:read)
|
652
|
+
if eof
|
653
|
+
length ? nil : ""
|
654
|
+
else
|
655
|
+
if length
|
656
|
+
@read_buffer ||= ""
|
657
|
+
fetched = false
|
658
|
+
while @read_buffer.length < length && !eof?
|
659
|
+
@read_buffer << gets.to_s
|
660
|
+
fetched = true
|
661
|
+
end
|
662
|
+
result = @read_buffer[0...length]
|
663
|
+
@read_buffer = @read_buffer[length..-1] || ""
|
664
|
+
if fetched
|
665
|
+
@pos -= @read_buffer.length
|
666
|
+
else
|
667
|
+
@pos += result.length
|
668
|
+
end
|
669
|
+
else
|
670
|
+
result = readlines.join
|
671
|
+
end
|
672
|
+
buffer ? buffer.replace(buffer + result) : result
|
673
|
+
end
|
537
674
|
end
|
538
675
|
|
539
676
|
# ios.read_nonblock(maxlen) => string
|
@@ -566,7 +703,14 @@ module Redisk
|
|
566
703
|
# read data is obtainable via its data method.
|
567
704
|
#
|
568
705
|
def readbytes(n)
|
569
|
-
|
706
|
+
result = read(n)
|
707
|
+
if result && result.length < n
|
708
|
+
raise TruncatedDataError, result
|
709
|
+
elsif result.nil?
|
710
|
+
raise EOFError, "You have reached the end of the IO stream"
|
711
|
+
else
|
712
|
+
result
|
713
|
+
end
|
570
714
|
end
|
571
715
|
|
572
716
|
# ios.readchar => fixnum
|
@@ -595,6 +739,7 @@ module Redisk
|
|
595
739
|
# f = File.new("testfile")
|
596
740
|
# f.readlines[0] #=> "This is line one\n"
|
597
741
|
def readlines
|
742
|
+
check_stream_open!(:read)
|
598
743
|
self.class.readlines(name)
|
599
744
|
end
|
600
745
|
|
@@ -678,6 +823,7 @@ module Redisk
|
|
678
823
|
# f.readline #=> "This is line one\n"
|
679
824
|
def rewind
|
680
825
|
self.lineno = 0
|
826
|
+
self.pos = 0
|
681
827
|
end
|
682
828
|
|
683
829
|
# scanf(str,&b)
|
@@ -727,6 +873,19 @@ module Redisk
|
|
727
873
|
# f.seek(-13, IO::SEEK_END) #=> 0
|
728
874
|
# f.readline #=> "And so on...\n"
|
729
875
|
def seek(offset, whence = SEEK_SET)
|
876
|
+
case whence
|
877
|
+
when SEEK_SET
|
878
|
+
self.pos = offset
|
879
|
+
when SEEK_END
|
880
|
+
self.pos = size + offset
|
881
|
+
when SEEK_CUR
|
882
|
+
self.pos += offset
|
883
|
+
end
|
884
|
+
0
|
885
|
+
end
|
886
|
+
|
887
|
+
# works just like seek, but seeks by lineno instead of pos
|
888
|
+
def seek_lines(offset, whence = SEEK_SET)
|
730
889
|
case whence
|
731
890
|
when SEEK_SET
|
732
891
|
self.lineno = offset
|
@@ -815,6 +974,7 @@ module Redisk
|
|
815
974
|
else
|
816
975
|
redis.ltrim list_key, -size, -1
|
817
976
|
end
|
977
|
+
stat.write_attribute(:size, @size = true_size)
|
818
978
|
length
|
819
979
|
end
|
820
980
|
|
@@ -829,10 +989,20 @@ module Redisk
|
|
829
989
|
# c = f.getc #=> 84
|
830
990
|
# f.ungetc(c) #=> nil
|
831
991
|
# f.getc #=> 84
|
832
|
-
def ungetc(
|
833
|
-
|
992
|
+
def ungetc(integer)
|
993
|
+
check_stream_open!(:write)
|
994
|
+
char = ("" << integer)
|
995
|
+
self << char
|
996
|
+
nil
|
834
997
|
end
|
835
998
|
|
999
|
+
# Removes all references to the IO and closes it for reading and writing
|
1000
|
+
def unlink
|
1001
|
+
close
|
1002
|
+
self.class.unlink(name)
|
1003
|
+
end
|
1004
|
+
alias :delete :unlink
|
1005
|
+
|
836
1006
|
# ios.write(string) => integer
|
837
1007
|
# Writes the given string to ios. The stream must be opened for writing.
|
838
1008
|
# If the argument is not a string, it will be converted to a string using
|
@@ -845,8 +1015,9 @@ module Redisk
|
|
845
1015
|
# This is a test
|
846
1016
|
# That was 15 bytes of data
|
847
1017
|
def write(string)
|
1018
|
+
check_stream_open!(:write)
|
848
1019
|
string = string.to_s
|
849
|
-
|
1020
|
+
self << string
|
850
1021
|
flush
|
851
1022
|
string.length
|
852
1023
|
end
|
@@ -863,5 +1034,10 @@ module Redisk
|
|
863
1034
|
def write_nonblock(string)
|
864
1035
|
end
|
865
1036
|
|
1037
|
+
private
|
1038
|
+
def check_stream_open!(stream = :read)
|
1039
|
+
raise(IOError, "#{self} is not open for #{stream}ing") unless open?(stream)
|
1040
|
+
end
|
1041
|
+
|
866
1042
|
end
|
867
1043
|
end
|
data/lib/redisk.rb
CHANGED
@@ -6,7 +6,7 @@ require 'redisk/io'
|
|
6
6
|
require 'redisk/logger'
|
7
7
|
|
8
8
|
module Redisk
|
9
|
-
VERSION = '0.
|
9
|
+
VERSION = '0.2.0'
|
10
10
|
|
11
11
|
extend self
|
12
12
|
|
@@ -33,5 +33,22 @@ module Redisk
|
|
33
33
|
self.redis
|
34
34
|
end
|
35
35
|
|
36
|
+
def io(*args)
|
37
|
+
Redisk::IO.new(*args)
|
38
|
+
end
|
39
|
+
|
40
|
+
def logger(*args)
|
41
|
+
Redisk::Logger.new(*args)
|
42
|
+
end
|
43
|
+
|
36
44
|
end
|
37
45
|
|
46
|
+
class String
|
47
|
+
|
48
|
+
if !method_defined?(:ord)
|
49
|
+
def ord
|
50
|
+
self[0]
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
data/redisk.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{redisk}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.2.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Aaron Quint"]
|
12
|
-
s.date = %q{2009-12-
|
12
|
+
s.date = %q{2009-12-22}
|
13
13
|
s.description = %q{Redisk includes Redisk::IO which is ~ Ruby's stdlib IO. It can be used with stdlib's Logger to log directly to redis}
|
14
14
|
s.email = %q{aaron@quirkey.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -19,9 +19,12 @@ Gem::Specification.new do |s|
|
|
19
19
|
s.files = [
|
20
20
|
".document",
|
21
21
|
".gitignore",
|
22
|
+
"HISTORY",
|
22
23
|
"LICENSE",
|
23
24
|
"README.rdoc",
|
24
25
|
"Rakefile",
|
26
|
+
"examples/rails.rb",
|
27
|
+
"examples/yajl.rb",
|
25
28
|
"lib/redisk.rb",
|
26
29
|
"lib/redisk/helper.rb",
|
27
30
|
"lib/redisk/io.rb",
|
@@ -45,7 +48,9 @@ Gem::Specification.new do |s|
|
|
45
48
|
"spec/redisk_io_spec.rb",
|
46
49
|
"spec/redisk_logger_spec.rb",
|
47
50
|
"spec/redisk_stat_spec.rb",
|
48
|
-
"spec/spec_helper.rb"
|
51
|
+
"spec/spec_helper.rb",
|
52
|
+
"examples/rails.rb",
|
53
|
+
"examples/yajl.rb"
|
49
54
|
]
|
50
55
|
|
51
56
|
if s.respond_to? :specification_version then
|
data/spec/redisk_io_spec.rb
CHANGED
@@ -2,6 +2,7 @@ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
|
2
2
|
|
3
3
|
describe Redisk::IO do
|
4
4
|
before do
|
5
|
+
FileUtils.mkdir_p('tmp')
|
5
6
|
# load a file into an IO object
|
6
7
|
@io_name = 'rails.log'
|
7
8
|
@key = Redisk::IO.list_key(@io_name)
|
@@ -14,7 +15,9 @@ describe Redisk::IO do
|
|
14
15
|
end
|
15
16
|
|
16
17
|
after do
|
17
|
-
Redisk.redis.
|
18
|
+
Redisk.redis.keys(@key.gsub(':_list', '*')).each do |key|
|
19
|
+
Redisk.redis.del key.gsub('redisk:', '')
|
20
|
+
end
|
18
21
|
end
|
19
22
|
|
20
23
|
describe 'new' do
|
@@ -29,6 +32,15 @@ describe Redisk::IO do
|
|
29
32
|
it 'stores the name of the key' do
|
30
33
|
@io.name.should == @io_name
|
31
34
|
end
|
35
|
+
|
36
|
+
it 'should be open' do
|
37
|
+
@io.closed?.should == false
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'should add to the list of ios' do
|
41
|
+
Redisk::IO.all.should include(@io_name)
|
42
|
+
end
|
43
|
+
|
32
44
|
end
|
33
45
|
|
34
46
|
describe 'foreach' do
|
@@ -45,6 +57,45 @@ describe Redisk::IO do
|
|
45
57
|
|
46
58
|
end
|
47
59
|
|
60
|
+
describe 'from_file' do
|
61
|
+
before(:each) do
|
62
|
+
Redisk::IO.unlink('dump_test.log')
|
63
|
+
File.open('tmp/dump_test.log', 'w+') {|f| f << "This is a file" }
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'should write into io at name from file' do
|
67
|
+
@io = Redisk::IO.from_file('dump_test.log', 'tmp/dump_test.log')
|
68
|
+
@io.rewind
|
69
|
+
@io.gets.should == "This is a file"
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'should write into io at name from File' do
|
73
|
+
@io = Redisk::IO.from_file('dump_test.log', File.new('tmp/dump_test.log'))
|
74
|
+
@io.rewind
|
75
|
+
@io.gets.should == "This is a file"
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
describe 'to_file' do
|
81
|
+
before(:each) do
|
82
|
+
Redisk::IO.unlink('dump_test.log')
|
83
|
+
File.unlink('tmp/dump_test.log')
|
84
|
+
Redisk::IO.open('dump_test.log') {|io| io << 'This is an IO' }
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'should write into file from io' do
|
88
|
+
Redisk::IO.to_file('dump_test.log', 'tmp/dump_test.log')
|
89
|
+
File.read('tmp/dump_test.log').should == 'This is an IO'
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'should write into File from io' do
|
93
|
+
Redisk::IO.to_file('dump_test.log', File.open('tmp/dump_test.log', 'w'))
|
94
|
+
File.read('tmp/dump_test.log').should == 'This is an IO'
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
|
48
99
|
describe 'open' do
|
49
100
|
|
50
101
|
it 'should return an IO object if no block is given' do
|
@@ -68,15 +119,32 @@ describe Redisk::IO do
|
|
68
119
|
describe 'read' do
|
69
120
|
|
70
121
|
it 'should return the entire contents without arguments' do
|
71
|
-
Redisk::IO.read(@io_name).should == @file_as_array.join("
|
122
|
+
Redisk::IO.read(@io_name).should == @file_as_array.join("")
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'should return the first [length] bytes' do
|
126
|
+
Redisk::IO.read(@io_name, 2).should == @file_as_array[0][0..1]
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'should return [length] contents starting at [offset]' do
|
130
|
+
Redisk::IO.read(@io_name, 2, 2).should == @file_as_array[0][2..3]
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|
134
|
+
|
135
|
+
|
136
|
+
describe 'read_lines' do
|
137
|
+
|
138
|
+
it 'should return the entire contents without arguments' do
|
139
|
+
Redisk::IO.read_lines(@io_name).should == @file_as_array.join("")
|
72
140
|
end
|
73
141
|
|
74
142
|
it 'should return the first [length] contents' do
|
75
|
-
Redisk::IO.
|
143
|
+
Redisk::IO.read_lines(@io_name, 2).should == @file_as_array[0..1].join("")
|
76
144
|
end
|
77
145
|
|
78
146
|
it 'should return [length] contents starting at [offset]' do
|
79
|
-
Redisk::IO.
|
147
|
+
Redisk::IO.read_lines(@io_name, 2, 2).should == @file_as_array[2..3].join("")
|
80
148
|
end
|
81
149
|
|
82
150
|
end
|
@@ -99,7 +167,7 @@ describe Redisk::IO do
|
|
99
167
|
it 'should append a line to the io' do
|
100
168
|
@io << 'whu'
|
101
169
|
@io.lineno = 100
|
102
|
-
@io.gets.should ==
|
170
|
+
@io.gets.should == "whu"
|
103
171
|
end
|
104
172
|
|
105
173
|
it 'should return the text' do
|
@@ -109,10 +177,56 @@ describe Redisk::IO do
|
|
109
177
|
it 'should be able to chain' do
|
110
178
|
@io << 'whu ' << 'zuh'
|
111
179
|
@io.lineno = 100
|
112
|
-
@io.gets.should ==
|
180
|
+
@io.gets.should == "whu zuh"
|
113
181
|
end
|
114
182
|
|
115
183
|
end
|
184
|
+
|
185
|
+
describe '#close_read' do
|
186
|
+
|
187
|
+
it 'should close the io for reading' do
|
188
|
+
@io.close_read
|
189
|
+
lambda {
|
190
|
+
@io.gets
|
191
|
+
}.should raise_error(IOError)
|
192
|
+
end
|
193
|
+
|
194
|
+
end
|
195
|
+
|
196
|
+
describe '#close_write' do
|
197
|
+
it 'should close the io for writing' do
|
198
|
+
@io.close_write
|
199
|
+
lambda {
|
200
|
+
@io.puts
|
201
|
+
}.should raise_error(IOError)
|
202
|
+
end
|
203
|
+
|
204
|
+
end
|
205
|
+
|
206
|
+
describe '#close' do
|
207
|
+
|
208
|
+
it 'should close for reading and writing' do
|
209
|
+
@io.close
|
210
|
+
lambda {
|
211
|
+
@io.puts
|
212
|
+
}.should raise_error(IOError)
|
213
|
+
lambda {
|
214
|
+
@io.gets
|
215
|
+
}.should raise_error(IOError)
|
216
|
+
end
|
217
|
+
|
218
|
+
end
|
219
|
+
|
220
|
+
describe '#closed?' do
|
221
|
+
|
222
|
+
it 'should only return true if both streams are closed' do
|
223
|
+
@io.close_read
|
224
|
+
@io.closed?.should == false
|
225
|
+
@io.close_write
|
226
|
+
@io.closed?.should == true
|
227
|
+
end
|
228
|
+
|
229
|
+
end
|
116
230
|
|
117
231
|
describe '#each' do
|
118
232
|
|
@@ -136,7 +250,29 @@ describe Redisk::IO do
|
|
136
250
|
end
|
137
251
|
|
138
252
|
end
|
139
|
-
|
253
|
+
|
254
|
+
describe '#each_byte' do
|
255
|
+
|
256
|
+
it 'should yield each byte as a fixnum to a block' do
|
257
|
+
i = 0
|
258
|
+
all_bytes = @file_as_array.join('')
|
259
|
+
@io.each_byte {|b|
|
260
|
+
b.should be_kind_of(Fixnum)
|
261
|
+
b.should == all_bytes[i].ord
|
262
|
+
i+=1
|
263
|
+
}
|
264
|
+
end
|
265
|
+
|
266
|
+
it 'should advance the pos of the io' do
|
267
|
+
i = 0
|
268
|
+
@io.each_byte {|b|
|
269
|
+
i+=1
|
270
|
+
@io.pos.should == i
|
271
|
+
}
|
272
|
+
end
|
273
|
+
|
274
|
+
end
|
275
|
+
|
140
276
|
describe '#eof' do
|
141
277
|
|
142
278
|
it 'should return false if lineno is not the end of the file' do
|
@@ -150,6 +286,28 @@ describe Redisk::IO do
|
|
150
286
|
|
151
287
|
end
|
152
288
|
|
289
|
+
describe '#getc' do
|
290
|
+
|
291
|
+
it 'should get the next byte from the file as a fixnum' do
|
292
|
+
val = @io.getc
|
293
|
+
val.should be_kind_of(Fixnum)
|
294
|
+
val.should == @file_as_array[0].ord
|
295
|
+
end
|
296
|
+
|
297
|
+
it 'should increment the pos of the io' do
|
298
|
+
@io.getc
|
299
|
+
@io.pos.should == 1
|
300
|
+
@io.getc
|
301
|
+
@io.pos.should == 2
|
302
|
+
end
|
303
|
+
|
304
|
+
it 'should get the next line if necessary' do
|
305
|
+
@io.pos = @file_as_array[0].length + 1
|
306
|
+
@io.getc.should == @file_as_array[1][0].ord
|
307
|
+
end
|
308
|
+
|
309
|
+
end
|
310
|
+
|
153
311
|
describe '#gets' do
|
154
312
|
|
155
313
|
it 'should return the next line from the io' do
|
@@ -185,12 +343,35 @@ describe Redisk::IO do
|
|
185
343
|
@io.gets.should == @file_as_array[50]
|
186
344
|
end
|
187
345
|
end
|
346
|
+
|
347
|
+
describe '#pos' do
|
348
|
+
|
349
|
+
it 'should return the current pos' do
|
350
|
+
@io.pos.should == 0
|
351
|
+
end
|
352
|
+
|
353
|
+
end
|
354
|
+
|
355
|
+
describe '#pos=' do
|
356
|
+
|
357
|
+
it 'should set the pos' do
|
358
|
+
@io.pos = 5
|
359
|
+
@io.pos.should == 5
|
360
|
+
@io.getc.should == @file_as_array[0][5].ord
|
361
|
+
end
|
362
|
+
|
363
|
+
it 'should set the lineno based on the pos' do
|
364
|
+
@io.pos = @file_as_array[0].length + 2
|
365
|
+
@io.lineno.should == 2
|
366
|
+
end
|
367
|
+
|
368
|
+
end
|
188
369
|
|
189
370
|
describe '#print' do
|
190
371
|
|
191
372
|
it 'should append arguments into a string and write to io' do
|
192
373
|
@io.print('My ', 'name ', 'is ', 'redisk')
|
193
|
-
line = Redisk::IO.
|
374
|
+
line = Redisk::IO.read_lines(@io_name, 1, 100)
|
194
375
|
line.should == 'My name is redisk'
|
195
376
|
end
|
196
377
|
|
@@ -201,7 +382,7 @@ describe Redisk::IO do
|
|
201
382
|
it 'should write the contents of $_ if no arguments are provided' do
|
202
383
|
@io.gets
|
203
384
|
@io.print
|
204
|
-
line = Redisk::IO.
|
385
|
+
line = Redisk::IO.read_lines(@io_name, 1, 100)
|
205
386
|
line.should == @file_as_array[0]
|
206
387
|
end
|
207
388
|
end
|
@@ -210,7 +391,7 @@ describe Redisk::IO do
|
|
210
391
|
|
211
392
|
it 'should run the arguments through sprintf and print to the io' do
|
212
393
|
@io.printf('My name is %s', 'redisk')
|
213
|
-
line = Redisk::IO.
|
394
|
+
line = Redisk::IO.read_lines(@io_name, 1, 100)
|
214
395
|
line.should == 'My name is redisk'
|
215
396
|
end
|
216
397
|
|
@@ -221,19 +402,68 @@ describe Redisk::IO do
|
|
221
402
|
it 'should write each argument to the io' do
|
222
403
|
@io.puts('1', '2', '3')
|
223
404
|
@io.lineno = 100
|
224
|
-
@io.gets.should ==
|
225
|
-
@io.gets.should ==
|
226
|
-
@io.gets.should ==
|
405
|
+
@io.gets.should == "1\n"
|
406
|
+
@io.gets.should == "2\n"
|
407
|
+
@io.gets.should == "3\n"
|
227
408
|
end
|
228
409
|
|
229
410
|
it 'should write a blank string if no argument is passed' do
|
230
411
|
@io.puts
|
231
412
|
@io.lineno = 100
|
232
|
-
@io.gets.should ==
|
413
|
+
@io.gets.should == "\n"
|
233
414
|
end
|
234
415
|
|
235
416
|
end
|
236
417
|
|
418
|
+
describe '#read' do
|
419
|
+
|
420
|
+
it 'should read to the end of the file if [length] is ommited' do
|
421
|
+
@io.read.should == @file_as_array.join("")
|
422
|
+
end
|
423
|
+
|
424
|
+
it 'should read into the [buffer] if a buffer is passed' do
|
425
|
+
string = "new string\n"
|
426
|
+
@io.read(nil, string)
|
427
|
+
string.should == "new string\n" + @file_as_array.join("")
|
428
|
+
end
|
429
|
+
|
430
|
+
it 'should read [length] bytes from the IO' do
|
431
|
+
val = @io.read(20)
|
432
|
+
val.length.should == 20
|
433
|
+
end
|
434
|
+
|
435
|
+
it 'should return nil if [length] is passed at the eof' do
|
436
|
+
@io.pos = 1000000
|
437
|
+
@io.eof?.should == true
|
438
|
+
@io.read(5).should == nil
|
439
|
+
end
|
440
|
+
|
441
|
+
it 'should return "" if no [length] is passed at the eof' do
|
442
|
+
@io.pos = 1000000
|
443
|
+
@io.eof?.should == true
|
444
|
+
@io.read(nil).should == ""
|
445
|
+
end
|
446
|
+
|
447
|
+
end
|
448
|
+
|
449
|
+
describe '#readbytes' do
|
450
|
+
|
451
|
+
it 'should read [n] bytes from the io' do
|
452
|
+
val = @io.readbytes(10)
|
453
|
+
val.length.should == 10
|
454
|
+
val.should == @file_as_array.join("")[0...10]
|
455
|
+
end
|
456
|
+
|
457
|
+
it 'should raise EOFError if the data is nil' do
|
458
|
+
@io.each_byte {|b| b }
|
459
|
+
@io.eof?.should == true
|
460
|
+
lambda {
|
461
|
+
@io.readbytes(10)
|
462
|
+
}.should raise_error(EOFError)
|
463
|
+
end
|
464
|
+
|
465
|
+
end
|
466
|
+
|
237
467
|
describe '#readline' do
|
238
468
|
|
239
469
|
it 'should read the next line with gets' do
|
@@ -270,26 +500,26 @@ describe Redisk::IO do
|
|
270
500
|
|
271
501
|
describe '#seek' do
|
272
502
|
|
273
|
-
it 'should set the
|
503
|
+
it 'should set the pos to the absolute location' do
|
274
504
|
@io.seek(10)
|
275
|
-
@io.
|
505
|
+
@io.pos.should == 10
|
276
506
|
end
|
277
507
|
|
278
|
-
it 'should set the
|
508
|
+
it 'should set the pos to the absolute location with SEEK_SET' do
|
279
509
|
@io.seek(15, IO::SEEK_SET)
|
280
|
-
@io.
|
510
|
+
@io.pos.should == 15
|
281
511
|
end
|
282
512
|
|
283
|
-
it 'should set the
|
513
|
+
it 'should set the pos to the location relative to the end with SEEK_END' do
|
284
514
|
@io.seek(-5, IO::SEEK_END)
|
285
|
-
@io.
|
515
|
+
@io.pos.should == @file_as_array.join.length - 5
|
286
516
|
end
|
287
517
|
|
288
|
-
it 'should set the
|
289
|
-
@io.
|
290
|
-
@io.
|
518
|
+
it 'should set the pos to an offset position from the current line with SEEK_CUR' do
|
519
|
+
@io.pos = 5
|
520
|
+
@io.pos.should == 5
|
291
521
|
@io.seek(5, IO::SEEK_CUR)
|
292
|
-
@io.
|
522
|
+
@io.pos.should == 10
|
293
523
|
end
|
294
524
|
|
295
525
|
end
|
@@ -300,7 +530,7 @@ describe Redisk::IO do
|
|
300
530
|
@stat = @io.stat
|
301
531
|
@stat.should be_instance_of(Redisk::Stat)
|
302
532
|
@stat.atime.should be_instance_of(Time)
|
303
|
-
@stat.size.should
|
533
|
+
@stat.size.should be_instance_of(Fixnum)
|
304
534
|
end
|
305
535
|
|
306
536
|
end
|
@@ -329,6 +559,42 @@ describe Redisk::IO do
|
|
329
559
|
|
330
560
|
end
|
331
561
|
|
562
|
+
describe '#ungetc' do
|
563
|
+
|
564
|
+
it 'should put the string represented by a fixnum at the end of the io buffer' do
|
565
|
+
@io.ungetc 65
|
566
|
+
@io.flush
|
567
|
+
last_char = nil
|
568
|
+
@io.each_byte {|b| last_char = b }
|
569
|
+
last_char.should == 65
|
570
|
+
end
|
571
|
+
|
572
|
+
it 'should return nil' do
|
573
|
+
@io.ungetc(65).should == nil
|
574
|
+
end
|
575
|
+
|
576
|
+
end
|
577
|
+
|
578
|
+
describe '#unlink' do
|
579
|
+
before do
|
580
|
+
@io.unlink
|
581
|
+
end
|
582
|
+
|
583
|
+
it 'should delete all keys associated with the io' do
|
584
|
+
Redisk.redis.get(@key).should == nil
|
585
|
+
Redisk::Stat.new(@key).size.should == 0
|
586
|
+
end
|
587
|
+
|
588
|
+
it 'should close the stream' do
|
589
|
+
@io.closed?.should == true
|
590
|
+
end
|
591
|
+
|
592
|
+
it 'should remove the key from the list of ios' do
|
593
|
+
Redisk::IO.all.should_not include(@io_name)
|
594
|
+
end
|
595
|
+
|
596
|
+
end
|
597
|
+
|
332
598
|
end
|
333
599
|
|
334
600
|
describe 'As an interface for logger' do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redisk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aaron Quint
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-12-
|
12
|
+
date: 2009-12-22 00:00:00 -05:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -54,9 +54,12 @@ extra_rdoc_files:
|
|
54
54
|
files:
|
55
55
|
- .document
|
56
56
|
- .gitignore
|
57
|
+
- HISTORY
|
57
58
|
- LICENSE
|
58
59
|
- README.rdoc
|
59
60
|
- Rakefile
|
61
|
+
- examples/rails.rb
|
62
|
+
- examples/yajl.rb
|
60
63
|
- lib/redisk.rb
|
61
64
|
- lib/redisk/helper.rb
|
62
65
|
- lib/redisk/io.rb
|
@@ -103,3 +106,5 @@ test_files:
|
|
103
106
|
- spec/redisk_logger_spec.rb
|
104
107
|
- spec/redisk_stat_spec.rb
|
105
108
|
- spec/spec_helper.rb
|
109
|
+
- examples/rails.rb
|
110
|
+
- examples/yajl.rb
|