s3io 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +18 -0
- data/.travis.yml +11 -0
- data/Gemfile +13 -0
- data/LICENSE.txt +30 -0
- data/README.md +57 -0
- data/Rakefile +10 -0
- data/lib/s3io/version.rb +3 -0
- data/lib/s3io/wrapper.rb +88 -0
- data/lib/s3io.rb +17 -0
- data/s3io.gemspec +21 -0
- data/test/s3_test_data.csv +102 -0
- data/test/test_s3io.rb +16 -0
- data/test/test_s3io_wrapper.rb +128 -0
- metadata +94 -0
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
Copyright (c) 2012, Fiksu, Inc.
|
2
|
+
All rights reserved.
|
3
|
+
|
4
|
+
Redistribution and use in source and binary forms, with or without
|
5
|
+
modification, are permitted provided that the following conditions are
|
6
|
+
met:
|
7
|
+
|
8
|
+
o Redistributions of source code must retain the above copyright
|
9
|
+
notice, this list of conditions and the following disclaimer.
|
10
|
+
|
11
|
+
o Redistributions in binary form must reproduce the above copyright
|
12
|
+
notice, this list of conditions and the following disclaimer in the
|
13
|
+
documentation and/or other materials provided with the
|
14
|
+
distribution.
|
15
|
+
|
16
|
+
o Fiksu, Inc. nor the names of its contributors may be used to
|
17
|
+
endorse or promote products derived from this software without
|
18
|
+
specific prior written permission.
|
19
|
+
|
20
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
21
|
+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
22
|
+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
23
|
+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
24
|
+
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
25
|
+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
26
|
+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
27
|
+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
28
|
+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
29
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
30
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/README.md
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
# S3io
|
2
|
+
|
3
|
+
[](https://travis-ci.org/fiksu/s3io)
|
4
|
+
|
5
|
+
An IO-compatible wrapper for S3.
|
6
|
+
|
7
|
+
Amazon's official AWS SDK provides an API for S3 that isn't compatible with Ruby's standard IO class and its derivatives. This gem provides a thin wrapper around AWS SDK that makes it possible to access objects stored on S3 as if they were instances of File or StringIO classes.
|
8
|
+
|
9
|
+
Currently only reads are supported with writes support coming soon.
|
10
|
+
|
11
|
+
## Installation
|
12
|
+
|
13
|
+
Add this line to your application's Gemfile:
|
14
|
+
|
15
|
+
gem 's3io'
|
16
|
+
|
17
|
+
And then execute:
|
18
|
+
|
19
|
+
$ bundle
|
20
|
+
|
21
|
+
Or install it yourself as:
|
22
|
+
|
23
|
+
$ gem install s3io
|
24
|
+
|
25
|
+
## Usage
|
26
|
+
|
27
|
+
Once wrapped, S3 objects behave the way you'd expect from an ordinary IO object.
|
28
|
+
|
29
|
+
require 'aws-sdk'
|
30
|
+
require 's3io'
|
31
|
+
|
32
|
+
s3_object = S3.buckets['some-bucket'].objects['path/to/object']
|
33
|
+
io = S3io.new(s3object)
|
34
|
+
|
35
|
+
first_100_bytes = io.read(100) # reading first 100 bytes
|
36
|
+
|
37
|
+
io.rewind # back to the first byte
|
38
|
+
|
39
|
+
io.lines do |line|
|
40
|
+
puts line # Just printing lines one by one
|
41
|
+
end
|
42
|
+
|
43
|
+
io.pos = 42 # seek byte 42
|
44
|
+
|
45
|
+
puts io.read # and print everything from that byte to the end
|
46
|
+
|
47
|
+
## To do
|
48
|
+
|
49
|
+
* Write support
|
50
|
+
|
51
|
+
## Contributing
|
52
|
+
|
53
|
+
1. Fork it
|
54
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
55
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
56
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
57
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/lib/s3io/version.rb
ADDED
data/lib/s3io/wrapper.rb
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
module S3io
|
2
|
+
# This class wraps an AWS S3 object in order to provide IO-like API.
|
3
|
+
# S3 objects wrapped this way can be used in methods that would otherwise expect an instance of File, StringIO etc.
|
4
|
+
class Wrapper
|
5
|
+
|
6
|
+
# Default buffer size for line parser in bytes
|
7
|
+
LINE_BUFFER_SIZE = 5 * 1024 * 1024 # MiB
|
8
|
+
|
9
|
+
include Enumerable
|
10
|
+
|
11
|
+
# Current byte position in S3 object
|
12
|
+
attr_accessor :pos
|
13
|
+
|
14
|
+
# Options that were passed during initialization
|
15
|
+
attr_reader :options
|
16
|
+
|
17
|
+
# Wraps an AWS::S3::S3Object into IO-like object.
|
18
|
+
#
|
19
|
+
# @param [AWS::S3::S3Object] s3object an object to wrap
|
20
|
+
# @param [Hash] options options hash
|
21
|
+
# @option options [Integer] :line_buffer_size size of the buffer that is used for reading contents of S3 object when iterating over its lines
|
22
|
+
def initialize(s3object, options = {})
|
23
|
+
@s3object = s3object
|
24
|
+
@options = {
|
25
|
+
:line_buffer_size => (options[:line_buffer_size] || LINE_BUFFER_SIZE)
|
26
|
+
}
|
27
|
+
|
28
|
+
@pos = 0
|
29
|
+
end
|
30
|
+
|
31
|
+
# Reads data from S3 object.
|
32
|
+
#
|
33
|
+
# @param [Integer] bytes number of bytes to read
|
34
|
+
def read(bytes = nil)
|
35
|
+
content_length = @s3object.content_length
|
36
|
+
|
37
|
+
return '' if (@pos >= content_length) || (bytes == 0)
|
38
|
+
|
39
|
+
bytes ||= content_length
|
40
|
+
|
41
|
+
upper_bound = @pos + bytes - 1
|
42
|
+
upper_bound = (content_length - 1) if upper_bound >= content_length
|
43
|
+
|
44
|
+
data = @s3object.read :range => @pos..upper_bound
|
45
|
+
@pos = upper_bound + 1
|
46
|
+
|
47
|
+
return data
|
48
|
+
end
|
49
|
+
|
50
|
+
# Rewinds position to the very beginning of S3 object.
|
51
|
+
def rewind
|
52
|
+
@pos = 0
|
53
|
+
end
|
54
|
+
|
55
|
+
# Iterates over S3 object lines.
|
56
|
+
#
|
57
|
+
# @param [String] separator line separator string
|
58
|
+
def each(separator = $/)
|
59
|
+
return enum_for(:each, separator) unless block_given?
|
60
|
+
|
61
|
+
line = ''
|
62
|
+
newline_pos = nil
|
63
|
+
|
64
|
+
# Either trying to parse the remainder or reading some more data
|
65
|
+
while newline_pos || !(buffer = read(@options[:line_buffer_size])).empty?
|
66
|
+
prev_newline_pos = newline_pos || 0
|
67
|
+
newline_pos = buffer.index(separator, prev_newline_pos)
|
68
|
+
|
69
|
+
if newline_pos
|
70
|
+
line << buffer[prev_newline_pos..newline_pos]
|
71
|
+
newline_pos += 1
|
72
|
+
yield line
|
73
|
+
line = ''
|
74
|
+
else
|
75
|
+
line << buffer[prev_newline_pos..-1]
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# Flush the remainder if body doesn't end with separator
|
80
|
+
yield line unless line.empty?
|
81
|
+
|
82
|
+
return self
|
83
|
+
end
|
84
|
+
alias lines each
|
85
|
+
alias each_line each
|
86
|
+
|
87
|
+
end
|
88
|
+
end
|
data/lib/s3io.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require "s3io/version"
|
2
|
+
require "s3io/wrapper"
|
3
|
+
|
4
|
+
require "aws-sdk"
|
5
|
+
|
6
|
+
# A top-level module that provides an S3 wrapper class.
|
7
|
+
module S3io
|
8
|
+
# A shortcut for wrapping an S3 object
|
9
|
+
#
|
10
|
+
# @param [AWS::S3::S3Object] s3object an object to wrap
|
11
|
+
# @param [Hash] options options hash
|
12
|
+
# @option options [Integer] :line_buffer_size size of the buffer that is used for reading contents of S3 object when iterating over its lines
|
13
|
+
# @return [S3io::Wrapper] a wrapped S3 object
|
14
|
+
def self.new(s3object, options = {})
|
15
|
+
Wrapper.new(s3object, options)
|
16
|
+
end
|
17
|
+
end
|
data/s3io.gemspec
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 's3io/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "s3io"
|
8
|
+
gem.version = S3io::VERSION
|
9
|
+
gem.authors = ["Arthur Pirogovski"]
|
10
|
+
gem.email = ["arthur@flyingtealeaf.com"]
|
11
|
+
gem.description = %q{An IO-compatible wrapper for S3}
|
12
|
+
gem.summary = %q{Amazon's official AWS SDK provides an API for S3 that isn't compatible with Ruby's standard IO class and its derivatives. This gem provides a thin wrapper around AWS SDK that makes it possible to access objects stored on S3 as if they were instances of File or StringIO classes.}
|
13
|
+
gem.homepage = "http://github.com/fiksu/s3io"
|
14
|
+
|
15
|
+
gem.add_dependency('aws-sdk')
|
16
|
+
|
17
|
+
gem.files = `git ls-files`.split($/)
|
18
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
19
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
20
|
+
gem.require_paths = ["lib"]
|
21
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
,,,,
|
2
|
+
Natalie,French,CO,Elmira,N7D 6Z8
|
3
|
+
Conan,Gross,YT,Jeffersonville,16555
|
4
|
+
Noel,Torres,Virginia,Roswell,09380
|
5
|
+
Veda,Serrano,British Columbia,Pullman,C2R 3U1
|
6
|
+
Ross,Gilmore,Prince Edward Island,Los Alamitos,13816
|
7
|
+
Melissa,Conley,PA,Bradford,42959
|
8
|
+
Cheyenne,Graves,AK,Flint,18721
|
9
|
+
Kelsey,Harding,Maryland,Pasadena,J8Z 8A9
|
10
|
+
Harding,Webb,PE,Bowie,70957
|
11
|
+
Derek,Nunez,Ontario,Temple City,X1P 7A3
|
12
|
+
Oliver,Williams,MO,Eau Claire,81691
|
13
|
+
Dacey,Olsen,Saskatchewan,Lebanon,H7E 3G8
|
14
|
+
George,Moss,NL,Vallejo,R8W 8O7
|
15
|
+
Wallace,Robbins,Newfoundland and Labrador,Belleville,63676
|
16
|
+
Tiger,Morris,KS,Little Falls,85473
|
17
|
+
Ebony,Franks,NY,Saginaw,X8B 5E6
|
18
|
+
Fallon,Singleton,Yukon,Commerce,R9A 2K7
|
19
|
+
Lester,Palmer,Prince Edward Island,Laurel,44859
|
20
|
+
Zena,Decker,GA,Winston-Salem,X2C 8D2
|
21
|
+
Diana,Vega,North Carolina,Covina,J2O 8Z0
|
22
|
+
Ocean,Weber,YT,Lebanon,O4G 6G3
|
23
|
+
Wade,Key,QC,Guthrie,57605
|
24
|
+
May,Cleveland,NU,Olean,X8Y 3A5
|
25
|
+
Kalia,Hensley,Alberta,Attleboro,85352
|
26
|
+
Jeremy,Brown,ON,Minneapolis,89868
|
27
|
+
Blaze,Mooney,Arizona,Rolling Hills Estates,C8H 9J6
|
28
|
+
Kaden,Morse,SC,Bowie,50748
|
29
|
+
Harper,Hansen,AB,Valparaiso,V4I 6P2
|
30
|
+
Ainsley,Edwards,ON,Connellsville,I2W 4Y3
|
31
|
+
Damon,Frazier,NM,Houma,02838
|
32
|
+
Jerome,Mcbride,Prince Edward Island,Phoenix,30148
|
33
|
+
Josephine,Herring,Wyoming,Barrow,74176
|
34
|
+
Alexa,Bowman,NS,Yukon,K7U 7S9
|
35
|
+
Colin,Middleton,ON,Suffolk,K5V 8Q5
|
36
|
+
Kylee,Murphy,KY,Hutchinson,P8A 4N7
|
37
|
+
Emily,Powell,IL,Princeton,Y2P 8A2
|
38
|
+
Gwendolyn,Matthews,AB,Elsmere,S8G 7F7
|
39
|
+
Kareem,Lee,Saskatchewan,Brookfield,20798
|
40
|
+
Portia,Carroll,Newfoundland and Labrador,Brockton,25318
|
41
|
+
Brianna,Hall,DE,Charleston,S3Q 9I3
|
42
|
+
Tanya,Colon,Alberta,Pascagoula,23877
|
43
|
+
Winifred,Michael,NL,Hornell,K4S 6C6
|
44
|
+
Zephr,Jones,NM,Caguas,26964
|
45
|
+
Nicole,Gallegos,Pennsylvania,New Madrid,96343
|
46
|
+
Amelia,Kent,AB,New Bedford,V7Y 1J8
|
47
|
+
Olivia,Schwartz,AB,Wisconsin Dells,V9L 4J8
|
48
|
+
Priscilla,Hawkins,PE,Orange,54645
|
49
|
+
Andrew,Gates,Saskatchewan,Rosemead,02306
|
50
|
+
Sean,Hicks,Nunavut,Eau Claire,S9D 3K8
|
51
|
+
Quentin,Alford,Oregon,Pomona,72996
|
52
|
+
Alana,Morin,NT,Auburn,N3F 4J4
|
53
|
+
Shay,Contreras,Saskatchewan,Santa Fe,X7B 2Q0
|
54
|
+
Steven,Morin,TX,Grand Island,08123
|
55
|
+
Keely,Padilla,AL,Fort Dodge,P6C 3S3
|
56
|
+
TaShya,Reid,New Hampshire,Franklin,Y2C 8J3
|
57
|
+
Brock,Tate,New Brunswick,Idaho Springs,N1X 6H6
|
58
|
+
Valentine,Casey,SD,Fond du Lac,U3I 8C6
|
59
|
+
Cassady,Cunningham,MB,San Mateo,33629
|
60
|
+
Tasha,Stone,West Virginia,Avalon,01425
|
61
|
+
Edan,Hammond,SC,Blythe,T9Q 2F2
|
62
|
+
Howard,Burgess,GA,Vincennes,55979
|
63
|
+
Desiree,Drake,Ontario,Duquesne,I3C 3W2
|
64
|
+
Hyacinth,Byrd,WV,Lake Charles,L4B 1J8
|
65
|
+
Zia,Moran,New Brunswick,Lynwood,38040
|
66
|
+
Sydnee,Parrish,Alberta,Fort Dodge,77918
|
67
|
+
Wyoming,Lowery,Yukon,LaGrange,G9Y 6V9
|
68
|
+
Anthony,Underwood,PE,Janesville,L9X 2X0
|
69
|
+
Allen,Stevens,Ontario,Bell Gardens,O3G 5X0
|
70
|
+
Ivory,White,NB,South El Monte,22714
|
71
|
+
Nasim,Cotton,NU,Nashua,48071
|
72
|
+
Laura,Olson,AB,Hastings,42464
|
73
|
+
Dahlia,Sheppard,Saskatchewan,St. Marys,84133
|
74
|
+
Dora,Carey,NC,Lakewood,18460
|
75
|
+
Vernon,Fulton,MB,Covington,O1R 5N8
|
76
|
+
Sacha,Snider,WI,West Palm Beach,28013
|
77
|
+
Merritt,Contreras,YT,Fallon,32049
|
78
|
+
Kendall,Warner,Newfoundland and Labrador,Bowling Green,10748
|
79
|
+
Rudyard,Leonard,NS,Las Vegas,67390
|
80
|
+
Iris,Hayden,YT,Cedar Falls,62673
|
81
|
+
Jasper,Cooper,MD,Kona,29787
|
82
|
+
Aurora,Sparks,NS,Natchez,87459
|
83
|
+
Bianca,Ford,MO,Dickinson,66786
|
84
|
+
James,Roach,Nunavut,Troy,55532
|
85
|
+
Yeo,Sykes,Nevada,Peoria,N9Y 2Q7
|
86
|
+
Anjolie,Dudley,QC,Pullman,36382
|
87
|
+
Neville,Campbell,Indiana,West Hartford,40449
|
88
|
+
Madeson,Atkins,TN,Sutter Creek,96232
|
89
|
+
Lynn,Delacruz,ND,Rolling Hills Estates,67917
|
90
|
+
Hadassah,May,LA,Suffolk,E7T 2J0
|
91
|
+
Kaseem,Mcpherson,PE,Salem,87566
|
92
|
+
Phelan,Gates,Alaska,Huntington,76853
|
93
|
+
Amaya,Sullivan,NU,Moultrie,L4Y 3C5
|
94
|
+
Uma,Riggs,NB,Schenectady,65323
|
95
|
+
Scarlet,Mullen,PE,Butler,U2T 2C0
|
96
|
+
Elijah,Mcpherson,HI,La Verne,69112
|
97
|
+
Jolie,Massey,BC,Worland,I3W 5A0
|
98
|
+
Leo,Bond,MB,Fairfax,O8X 5Z0
|
99
|
+
Remedios,Jimenez,North Carolina,Seattle,71966
|
100
|
+
Wynne,Nixon,AB,Hanahan,36015
|
101
|
+
Kyra,Chandler,NL,Edina,00572
|
102
|
+
|
data/test/test_s3io.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 's3io'
|
3
|
+
|
4
|
+
class S3ioTest < Test::Unit::TestCase
|
5
|
+
def test_s3io_new
|
6
|
+
s3object = Object.new
|
7
|
+
wrapper = S3io.new(s3object)
|
8
|
+
assert_equal(S3io::Wrapper, wrapper.class)
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_s3io_new_with_options
|
12
|
+
s3object = Object.new
|
13
|
+
wrapper = S3io.new(s3object, :line_buffer_size => 128)
|
14
|
+
assert_equal(128, wrapper.options[:line_buffer_size])
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 's3io'
|
3
|
+
require 'stringio'
|
4
|
+
|
5
|
+
# Emulate S3Object in a way that allows us to check if its methods are being called properly
|
6
|
+
class S3ObjectMock
|
7
|
+
def initialize(body = '')
|
8
|
+
@body = body
|
9
|
+
end
|
10
|
+
|
11
|
+
def read(options = {})
|
12
|
+
range = options[:range]
|
13
|
+
fail "The mock should be called with a :range option" unless range
|
14
|
+
|
15
|
+
return @body[range]
|
16
|
+
end
|
17
|
+
|
18
|
+
def content_length
|
19
|
+
@body.size
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class S3ioWrapperTest < Test::Unit::TestCase
|
24
|
+
S3_TEST_DATA = File.read('test/s3_test_data.csv')
|
25
|
+
|
26
|
+
def setup
|
27
|
+
@s3object = S3ObjectMock.new(S3_TEST_DATA)
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_s3io_wrapper_full_read
|
31
|
+
wrapper = S3io::Wrapper.new(@s3object)
|
32
|
+
|
33
|
+
assert_equal(S3_TEST_DATA, wrapper.read)
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_s3io_wrapper_zero_read
|
37
|
+
wrapper = S3io::Wrapper.new(@s3object)
|
38
|
+
|
39
|
+
assert_equal('', wrapper.read(0))
|
40
|
+
assert_equal(0, wrapper.pos)
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_s3io_wrapper_partial_read
|
44
|
+
wrapper = S3io::Wrapper.new(@s3object)
|
45
|
+
|
46
|
+
assert_equal(S3_TEST_DATA[0..99], wrapper.read(100))
|
47
|
+
assert_equal(S3_TEST_DATA[100..100], wrapper.read(1))
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_s3io_wrapper_each
|
51
|
+
wrapper = S3io::Wrapper.new(@s3object)
|
52
|
+
|
53
|
+
lines = []
|
54
|
+
wrapper.each do |line|
|
55
|
+
lines << line
|
56
|
+
end
|
57
|
+
|
58
|
+
assert_equal(S3_TEST_DATA.lines.to_a, lines)
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_s3io_wrapper_each_enum
|
62
|
+
wrapper = S3io::Wrapper.new(@s3object)
|
63
|
+
|
64
|
+
assert_equal(S3_TEST_DATA.lines.to_a,
|
65
|
+
wrapper.lines.to_a)
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_s3io_wrapper_pos
|
69
|
+
wrapper = S3io::Wrapper.new(@s3object)
|
70
|
+
|
71
|
+
assert_equal(0, wrapper.pos)
|
72
|
+
|
73
|
+
wrapper.pos = 77
|
74
|
+
|
75
|
+
assert_equal(77, wrapper.pos)
|
76
|
+
assert_equal(S3_TEST_DATA[77, 32], wrapper.read(32))
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_s3io_wrapper_pos_beyond
|
80
|
+
wrapper = S3io::Wrapper.new(@s3object)
|
81
|
+
|
82
|
+
pos_beyond = @s3object.content_length + 100
|
83
|
+
wrapper.pos = pos_beyond
|
84
|
+
|
85
|
+
assert_equal('', wrapper.read)
|
86
|
+
assert_equal(pos_beyond, wrapper.pos)
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_s3io_wrapper_rewind
|
90
|
+
wrapper = S3io::Wrapper.new(@s3object)
|
91
|
+
|
92
|
+
wrapper.lines do |line|
|
93
|
+
# iterate through all the lines
|
94
|
+
end
|
95
|
+
|
96
|
+
wrapper.rewind
|
97
|
+
assert_equal(0, wrapper.pos)
|
98
|
+
|
99
|
+
assert_equal(S3_TEST_DATA[0..100], wrapper.read(101))
|
100
|
+
end
|
101
|
+
|
102
|
+
def test_s3io_wrapper_line_buffer_size
|
103
|
+
wrapper = S3io::Wrapper.new(@s3object, :line_buffer_size => 25)
|
104
|
+
|
105
|
+
wrapper.lines.each_with_index do |line, index|
|
106
|
+
break if index == 1 # skip two buffered reads
|
107
|
+
end
|
108
|
+
|
109
|
+
assert_equal(50, wrapper.pos)
|
110
|
+
assert_equal(S3_TEST_DATA[50..-1], wrapper.read)
|
111
|
+
end
|
112
|
+
|
113
|
+
def test_s3io_wrapper_lines_custom_separator
|
114
|
+
wrapper = S3io::Wrapper.new(@s3object)
|
115
|
+
|
116
|
+
assert_equal(S3_TEST_DATA.lines(",").to_a, wrapper.lines(",").to_a)
|
117
|
+
end
|
118
|
+
|
119
|
+
def test_s3io_wrapper_empty_each
|
120
|
+
wrapper = S3io::Wrapper.new(S3ObjectMock.new(''))
|
121
|
+
|
122
|
+
wrapper.each do |line|
|
123
|
+
assert_equal(false, :never_gets_called)
|
124
|
+
end
|
125
|
+
|
126
|
+
assert_equal('', wrapper.read)
|
127
|
+
end
|
128
|
+
end
|
metadata
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: s3io
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Arthur Pirogovski
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2012-12-13 00:00:00 Z
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: aws-sdk
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
hash: 3
|
29
|
+
segments:
|
30
|
+
- 0
|
31
|
+
version: "0"
|
32
|
+
type: :runtime
|
33
|
+
version_requirements: *id001
|
34
|
+
description: An IO-compatible wrapper for S3
|
35
|
+
email:
|
36
|
+
- arthur@flyingtealeaf.com
|
37
|
+
executables: []
|
38
|
+
|
39
|
+
extensions: []
|
40
|
+
|
41
|
+
extra_rdoc_files: []
|
42
|
+
|
43
|
+
files:
|
44
|
+
- .gitignore
|
45
|
+
- .travis.yml
|
46
|
+
- Gemfile
|
47
|
+
- LICENSE.txt
|
48
|
+
- README.md
|
49
|
+
- Rakefile
|
50
|
+
- lib/s3io.rb
|
51
|
+
- lib/s3io/version.rb
|
52
|
+
- lib/s3io/wrapper.rb
|
53
|
+
- s3io.gemspec
|
54
|
+
- test/s3_test_data.csv
|
55
|
+
- test/test_s3io.rb
|
56
|
+
- test/test_s3io_wrapper.rb
|
57
|
+
homepage: http://github.com/fiksu/s3io
|
58
|
+
licenses: []
|
59
|
+
|
60
|
+
post_install_message:
|
61
|
+
rdoc_options: []
|
62
|
+
|
63
|
+
require_paths:
|
64
|
+
- lib
|
65
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
66
|
+
none: false
|
67
|
+
requirements:
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
hash: 3
|
71
|
+
segments:
|
72
|
+
- 0
|
73
|
+
version: "0"
|
74
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
75
|
+
none: false
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
hash: 3
|
80
|
+
segments:
|
81
|
+
- 0
|
82
|
+
version: "0"
|
83
|
+
requirements: []
|
84
|
+
|
85
|
+
rubyforge_project:
|
86
|
+
rubygems_version: 1.8.24
|
87
|
+
signing_key:
|
88
|
+
specification_version: 3
|
89
|
+
summary: Amazon's official AWS SDK provides an API for S3 that isn't compatible with Ruby's standard IO class and its derivatives. This gem provides a thin wrapper around AWS SDK that makes it possible to access objects stored on S3 as if they were instances of File or StringIO classes.
|
90
|
+
test_files:
|
91
|
+
- test/s3_test_data.csv
|
92
|
+
- test/test_s3io.rb
|
93
|
+
- test/test_s3io_wrapper.rb
|
94
|
+
has_rdoc:
|