s3io 1.1.1 → 1.1.4
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +4 -2
- data/Gemfile +2 -6
- data/README.md +3 -6
- data/lib/s3io/read_wrapper.rb +22 -12
- data/lib/s3io/version.rb +1 -1
- data/s3io.gemspec +4 -1
- data/test/test_s3io_read_wrapper.rb +35 -0
- metadata +58 -40
- checksums.yaml +0 -7
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -4,13 +4,13 @@
|
|
4
4
|
|
5
5
|
An IO-compatible wrapper for S3.
|
6
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.
|
7
|
+
Amazon's official AWS SDK (version 1) 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 (version 1) that makes it possible to access objects stored on S3 as if they were instances of File or StringIO classes.
|
8
8
|
|
9
|
-
|
9
|
+
Both streamed reads and writes are supported.
|
10
10
|
|
11
11
|
## Warning
|
12
12
|
|
13
|
-
Reads
|
13
|
+
Reads guarantee consistency if S3 file changes while being streamed, but only if versioning has been enabled for that file. S3io always reads from the same version of the file it read the first chunk from. If a non-versioned file is changed during the read process, an ```S3io::ReadModifiedError``` is thrown. To protect against this, enable versioning for the bucket where file is located. Lifecycle policy can be used to automatically delete older versions based on their age.
|
14
14
|
|
15
15
|
## Installation
|
16
16
|
|
@@ -62,9 +62,6 @@ It can write:
|
|
62
62
|
io.write 'def'
|
63
63
|
end
|
64
64
|
|
65
|
-
If the file is being changed during the read process, an ```S3io::ReadModifiedError``` is thrown.
|
66
|
-
|
67
|
-
|
68
65
|
## To do
|
69
66
|
|
70
67
|
* Code documentation
|
data/lib/s3io/read_wrapper.rb
CHANGED
@@ -30,30 +30,30 @@ module S3io
|
|
30
30
|
# Reads data from S3 object.
|
31
31
|
#
|
32
32
|
# @param [Integer] bytes number of bytes to read
|
33
|
-
def read(bytes = nil)
|
34
|
-
content_length
|
33
|
+
def read(bytes = nil, outbuf = nil)
|
34
|
+
@content_length ||= @s3object.content_length
|
35
35
|
|
36
|
-
return '' if (@pos >= content_length) || (bytes == 0)
|
36
|
+
return '' if (@pos >= @content_length) || (bytes == 0)
|
37
37
|
|
38
|
-
bytes ||= content_length
|
38
|
+
bytes ||= @content_length
|
39
39
|
|
40
40
|
upper_bound = @pos + bytes - 1
|
41
|
-
upper_bound = (content_length - 1) if upper_bound >= content_length
|
41
|
+
upper_bound = (@content_length - 1) if upper_bound >= @content_length
|
42
42
|
|
43
|
-
data = @s3object.read :range => @pos..upper_bound
|
44
|
-
|
45
|
-
last_modified = @s3object.last_modified
|
46
|
-
unless last_modified == @last_modified
|
47
|
-
fail ReadModifiedError, "S3 object #{@s3object.key} was updated during read, last_modified=#{last_modified.to_s} (was #{@last_modified.to_s})"
|
48
|
-
end
|
43
|
+
data = @s3object.read :range => @pos..upper_bound, :if_unmodified_since => @last_modified
|
49
44
|
|
50
45
|
@pos = upper_bound + 1
|
51
46
|
|
47
|
+
outbuf.replace data if outbuf
|
48
|
+
|
52
49
|
return data
|
50
|
+
|
51
|
+
rescue ::AWS::S3::Errors::PreconditionFailed
|
52
|
+
fail ReadModifiedError, "S3 object #{@s3object.key} was updated during read (modified since #{@last_modified.to_s})"
|
53
53
|
end
|
54
54
|
|
55
55
|
def eof?
|
56
|
-
@
|
56
|
+
(@content_length = @s3object.content_length) && (@pos >= @content_length)
|
57
57
|
end
|
58
58
|
|
59
59
|
# Rewinds position to the very beginning of S3 object.
|
@@ -92,5 +92,15 @@ module S3io
|
|
92
92
|
end
|
93
93
|
alias lines each
|
94
94
|
alias each_line each
|
95
|
+
|
96
|
+
# Returns one string at a time.
|
97
|
+
#
|
98
|
+
# @param [String] separator line separator string
|
99
|
+
def gets(separator = $/)
|
100
|
+
@_gets ||= enum_for(:each, separator)
|
101
|
+
@_gets.next
|
102
|
+
rescue StopIteration
|
103
|
+
nil
|
104
|
+
end
|
95
105
|
end
|
96
106
|
end
|
data/lib/s3io/version.rb
CHANGED
data/s3io.gemspec
CHANGED
@@ -12,10 +12,13 @@ Gem::Specification.new do |gem|
|
|
12
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
13
|
gem.homepage = "http://github.com/fiksu/s3io"
|
14
14
|
|
15
|
-
gem.add_dependency('aws-sdk')
|
15
|
+
gem.add_dependency('aws-sdk', "~> 1.64.0")
|
16
16
|
|
17
17
|
gem.files = `git ls-files`.split($/)
|
18
18
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
19
19
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
20
20
|
gem.require_paths = ["lib"]
|
21
|
+
if RUBY_VERSION >= '2.2'
|
22
|
+
gem.add_development_dependency "test-unit", "~> 3.0.8"
|
23
|
+
end
|
21
24
|
end
|
@@ -11,7 +11,10 @@ class S3ObjectReadMock
|
|
11
11
|
|
12
12
|
def read(options = {})
|
13
13
|
range = options[:range]
|
14
|
+
if_unmodified_since = options[:if_unmodified_since]
|
15
|
+
|
14
16
|
fail "The mock should be called with a :range option" unless range
|
17
|
+
fail AWS::S3::Errors::PreconditionFailed if if_unmodified_since && if_unmodified_since != @last_modified
|
15
18
|
|
16
19
|
return @body[range]
|
17
20
|
end
|
@@ -54,6 +57,16 @@ class S3ioReadWrapperTest < Test::Unit::TestCase
|
|
54
57
|
assert_equal(0, wrapper.pos)
|
55
58
|
end
|
56
59
|
|
60
|
+
def test_zero_outbuf_read
|
61
|
+
wrapper = S3io::ReadWrapper.new(@s3object)
|
62
|
+
data = String.new
|
63
|
+
|
64
|
+
wrapper.read(0,data)
|
65
|
+
|
66
|
+
assert_equal('', data)
|
67
|
+
assert_equal(0, wrapper.pos)
|
68
|
+
end
|
69
|
+
|
57
70
|
def test_partial_read
|
58
71
|
wrapper = S3io::ReadWrapper.new(@s3object)
|
59
72
|
|
@@ -71,6 +84,17 @@ class S3ioReadWrapperTest < Test::Unit::TestCase
|
|
71
84
|
end
|
72
85
|
end
|
73
86
|
|
87
|
+
def test_partial_outbuf_read
|
88
|
+
wrapper = S3io::ReadWrapper.new(@s3object)
|
89
|
+
data = String.new
|
90
|
+
|
91
|
+
wrapper.read(100, data)
|
92
|
+
assert_equal(S3_TEST_DATA[0..99], data)
|
93
|
+
|
94
|
+
wrapper.read(1, data)
|
95
|
+
assert_equal(S3_TEST_DATA[100..100], data)
|
96
|
+
end
|
97
|
+
|
74
98
|
def test_each
|
75
99
|
wrapper = S3io::ReadWrapper.new(@s3object)
|
76
100
|
|
@@ -166,4 +190,15 @@ class S3ioReadWrapperTest < Test::Unit::TestCase
|
|
166
190
|
|
167
191
|
assert_equal('', wrapper.read)
|
168
192
|
end
|
193
|
+
|
194
|
+
def test_gets
|
195
|
+
wrapper = S3io::ReadWrapper.new(@s3object)
|
196
|
+
|
197
|
+
lines = []
|
198
|
+
while line = wrapper.gets
|
199
|
+
lines << line
|
200
|
+
end
|
201
|
+
|
202
|
+
assert_equal(S3_TEST_DATA.lines.to_a, lines)
|
203
|
+
end
|
169
204
|
end
|
metadata
CHANGED
@@ -1,36 +1,48 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: s3io
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 1
|
8
|
+
- 1
|
9
|
+
- 4
|
10
|
+
version: 1.1.4
|
5
11
|
platform: ruby
|
6
|
-
authors:
|
12
|
+
authors:
|
7
13
|
- Arthur Pirogovski
|
8
14
|
autorequire:
|
9
15
|
bindir: bin
|
10
16
|
cert_chain: []
|
11
|
-
|
12
|
-
|
13
|
-
|
17
|
+
|
18
|
+
date: 2015-06-17 00:00:00 Z
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
14
21
|
name: aws-sdk
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - '>='
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '0'
|
20
|
-
type: :runtime
|
21
22
|
prerelease: false
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ~>
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
hash: 279
|
29
|
+
segments:
|
30
|
+
- 1
|
31
|
+
- 64
|
32
|
+
- 0
|
33
|
+
version: 1.64.0
|
34
|
+
type: :runtime
|
35
|
+
version_requirements: *id001
|
27
36
|
description: An IO-compatible wrapper for S3
|
28
|
-
email:
|
37
|
+
email:
|
29
38
|
- arthur@flyingtealeaf.com
|
30
39
|
executables: []
|
40
|
+
|
31
41
|
extensions: []
|
42
|
+
|
32
43
|
extra_rdoc_files: []
|
33
|
-
|
44
|
+
|
45
|
+
files:
|
34
46
|
- .gitignore
|
35
47
|
- .travis.yml
|
36
48
|
- Gemfile
|
@@ -48,32 +60,38 @@ files:
|
|
48
60
|
- test/test_s3io_write_wrapper.rb
|
49
61
|
homepage: http://github.com/fiksu/s3io
|
50
62
|
licenses: []
|
51
|
-
|
63
|
+
|
52
64
|
post_install_message:
|
53
65
|
rdoc_options: []
|
54
|
-
|
66
|
+
|
67
|
+
require_paths:
|
55
68
|
- lib
|
56
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
69
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
70
|
+
none: false
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
hash: 3
|
75
|
+
segments:
|
76
|
+
- 0
|
77
|
+
version: "0"
|
78
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
79
|
+
none: false
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
hash: 3
|
84
|
+
segments:
|
85
|
+
- 0
|
86
|
+
version: "0"
|
66
87
|
requirements: []
|
88
|
+
|
67
89
|
rubyforge_project:
|
68
|
-
rubygems_version:
|
90
|
+
rubygems_version: 1.8.24
|
69
91
|
signing_key:
|
70
|
-
specification_version:
|
71
|
-
summary: Amazon's official AWS SDK provides an API for S3 that isn't compatible with
|
72
|
-
|
73
|
-
AWS SDK that makes it possible to access objects stored on S3 as if they were instances
|
74
|
-
of File or StringIO classes.
|
75
|
-
test_files:
|
92
|
+
specification_version: 3
|
93
|
+
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.
|
94
|
+
test_files:
|
76
95
|
- test/s3_test_data.csv
|
77
96
|
- test/test_s3io_read_wrapper.rb
|
78
97
|
- test/test_s3io_write_wrapper.rb
|
79
|
-
has_rdoc:
|
checksums.yaml
DELETED
@@ -1,7 +0,0 @@
|
|
1
|
-
---
|
2
|
-
SHA1:
|
3
|
-
metadata.gz: 7a2e6b77b5d02864c35705178a360b3fe22e5708
|
4
|
-
data.tar.gz: cfae25b66b0488f008dbbde0cba612a07bb1a31c
|
5
|
-
SHA512:
|
6
|
-
metadata.gz: e9f64f80951bf058fbd12458f5a0f6e4c39a019d683e486df5ac80a55f3d3abb26f24de04f059a68726e2bf64bf08f788bee40ddba8a3cab1161cf474ab4e569
|
7
|
-
data.tar.gz: ff4cdd6ed29cba34834fc571df4c01d979910fd62effc8162872cdcc4456b32921d4b1a9db710ca5b140b0b0cdd638af722199da0e5260c4db4e38ce75566d4b
|