blobby 1.0.1 → 1.1.0
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.
- checksums.yaml +4 -4
- data/.rubocop.yml +7 -0
- data/CHANGES.md +7 -0
- data/README.md +13 -2
- data/blobby.gemspec +0 -2
- data/lib/blobby.rb +45 -0
- data/lib/blobby/abstract_store.rb +69 -0
- data/lib/blobby/fake_success_store.rb +1 -1
- data/lib/blobby/filesystem_store.rb +11 -5
- data/lib/blobby/http_store.rb +14 -9
- data/lib/blobby/in_memory_store.rb +5 -1
- data/lib/blobby/key_constraint.rb +2 -2
- data/lib/blobby/logging_store.rb +4 -3
- data/lib/blobby/version.rb +1 -1
- data/spec/blobby/composite_store_spec.rb +2 -0
- data/spec/blobby/fake_success_store_spec.rb +2 -0
- data/spec/blobby/filesystem_store_spec.rb +7 -3
- data/spec/blobby/http_store_spec.rb +12 -7
- data/spec/blobby/in_memory_store_spec.rb +2 -0
- data/spec/blobby/key_transforming_store_spec.rb +2 -0
- data/spec/blobby/logging_store_spec.rb +3 -1
- data/spec/blobby/store_behaviour.rb +6 -2
- data/spec/blobby_spec.rb +63 -0
- data/spec/spec_helper.rb +1 -0
- metadata +10 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0910a3f2446d9f9eb7cad9f724c8df57cc5d85ac
|
|
4
|
+
data.tar.gz: 2c26dc843a4a15c5894209b590f5b4d01078af14
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9c49f221a912ebbc99a8fadfa2e3643d98c004c1e040e0c0a87368a69c6050bd7a2581ce6824841a91343a8ec67ef8f915a91f16c28a97d5f8830d4d51661304
|
|
7
|
+
data.tar.gz: 86eeb3dd9fdfecd3864dc92d16ef087c38947cec898be4cdc5e02483b86eb6e108a0227121fafb40d1206126f9e10fe5d733c59a37c9bbe794e394081a1378ed
|
data/.rubocop.yml
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
Eval:
|
|
2
2
|
Exclude:
|
|
3
3
|
- "Rakefile"
|
|
4
|
+
- "**/version.rb"
|
|
4
5
|
|
|
5
6
|
Metrics/AbcSize:
|
|
6
7
|
Enabled: false
|
|
@@ -40,8 +41,14 @@ Style/FileName:
|
|
|
40
41
|
Style/HashSyntax:
|
|
41
42
|
EnforcedStyle: hash_rockets
|
|
42
43
|
|
|
44
|
+
Style/SignalException:
|
|
45
|
+
EnforcedStyle: semantic
|
|
46
|
+
|
|
43
47
|
Style/StringLiterals:
|
|
44
48
|
EnforcedStyle: double_quotes
|
|
45
49
|
|
|
50
|
+
Style/RegexpLiteral:
|
|
51
|
+
Enabled: false
|
|
52
|
+
|
|
46
53
|
Style/WordArray:
|
|
47
54
|
Enabled: false
|
data/CHANGES.md
ADDED
data/README.md
CHANGED
|
@@ -39,5 +39,16 @@ This gem provides several "store" implementations:
|
|
|
39
39
|
|
|
40
40
|
Other gems provide additional implementations:
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
* ["blobby-s3"](https://github.com/realestate-com-au/blobby-s3)
|
|
43
|
+
|
|
44
|
+
`Blobby.store` provides a convenient way to construct an appropriate
|
|
45
|
+
implementation, given a URI (or psuedo-URI):
|
|
46
|
+
|
|
47
|
+
Blobby.store("file:///tmp")
|
|
48
|
+
# => #<Blobby::FilesystemStore ...>
|
|
49
|
+
|
|
50
|
+
Blobby.store("mem:")
|
|
51
|
+
# => #<Blobby::InMemoryStore ...>
|
|
52
|
+
|
|
53
|
+
Blobby.store("http://storage.com/mystuff/")
|
|
54
|
+
# => #<Blobby::HttpStore ...>
|
data/blobby.gemspec
CHANGED
data/lib/blobby.rb
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
require "blobby/filesystem_store"
|
|
2
|
+
require "blobby/http_store"
|
|
3
|
+
require "blobby/in_memory_store"
|
|
4
|
+
require "blobby/version"
|
|
5
|
+
require "uri"
|
|
6
|
+
|
|
7
|
+
# BLOB storage.
|
|
8
|
+
#
|
|
9
|
+
module Blobby
|
|
10
|
+
|
|
11
|
+
class << self
|
|
12
|
+
|
|
13
|
+
# Instantiate a BLOB-store based on a storage-address URI.
|
|
14
|
+
# An appropriate store impementation will be selected, based on
|
|
15
|
+
# URI-scheme.
|
|
16
|
+
#
|
|
17
|
+
# @param uri [URI] storage address
|
|
18
|
+
#
|
|
19
|
+
def store(uri)
|
|
20
|
+
uri = URI(uri)
|
|
21
|
+
factory = store_factories[uri.scheme]
|
|
22
|
+
fail ArgumentError, "unknown store type: #{uri}" if factory.nil?
|
|
23
|
+
factory.from_uri(uri)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def register_store_factory(uri_scheme, factory)
|
|
27
|
+
store_factories[uri_scheme] = factory
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
|
|
32
|
+
def store_factories
|
|
33
|
+
@store_factories ||= {}
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
register_store_factory nil, FilesystemStore
|
|
39
|
+
register_store_factory "file", FilesystemStore
|
|
40
|
+
register_store_factory "http", HttpStore
|
|
41
|
+
register_store_factory "https", HttpStore
|
|
42
|
+
register_store_factory "in-memory", InMemoryStore
|
|
43
|
+
register_store_factory "mem", InMemoryStore
|
|
44
|
+
|
|
45
|
+
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
require "blobby/key_constraint"
|
|
2
|
+
|
|
3
|
+
module Blobby
|
|
4
|
+
|
|
5
|
+
# A store of BLOBs.
|
|
6
|
+
# @abstract
|
|
7
|
+
class AbstractStore
|
|
8
|
+
|
|
9
|
+
# @return true if the store is available for use
|
|
10
|
+
def available?
|
|
11
|
+
true
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Access an object in the store.
|
|
15
|
+
# @param key [String] object address
|
|
16
|
+
# @return [StoredObject] a handle to the addressed object
|
|
17
|
+
def [](key)
|
|
18
|
+
KeyConstraint.must_allow!(key)
|
|
19
|
+
StoredObject.new
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# A handle to an object in the BLOB-store.
|
|
23
|
+
# @abstract
|
|
24
|
+
class StoredObject
|
|
25
|
+
|
|
26
|
+
# Check for existence.
|
|
27
|
+
# @return true if the object exists
|
|
28
|
+
def exists?
|
|
29
|
+
false
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# @overload read
|
|
33
|
+
# Read BLOB data.
|
|
34
|
+
# @return [String] data if the object exists
|
|
35
|
+
# @return [nil] if the object doesn't exist
|
|
36
|
+
# @overload read
|
|
37
|
+
# Stream BLOB data in chunks.
|
|
38
|
+
# @yield [chunk] each chunk of data
|
|
39
|
+
# @return [void]
|
|
40
|
+
def read
|
|
41
|
+
content = @hash[key]
|
|
42
|
+
if block_given?
|
|
43
|
+
yield content
|
|
44
|
+
nil
|
|
45
|
+
else
|
|
46
|
+
content
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def write(content)
|
|
51
|
+
if content.respond_to?(:read)
|
|
52
|
+
content = content.read
|
|
53
|
+
else
|
|
54
|
+
content = content.to_str.dup
|
|
55
|
+
end
|
|
56
|
+
content = content.force_encoding("BINARY") if content.respond_to?(:force_encoding)
|
|
57
|
+
@hash[key] = content
|
|
58
|
+
nil
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def delete
|
|
62
|
+
!@hash.delete(key).nil?
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
end
|
|
@@ -10,6 +10,10 @@ module Blobby
|
|
|
10
10
|
#
|
|
11
11
|
class FilesystemStore
|
|
12
12
|
|
|
13
|
+
def self.from_uri(uri)
|
|
14
|
+
new(uri.path)
|
|
15
|
+
end
|
|
16
|
+
|
|
13
17
|
def initialize(dir, options = {}, &sharding_strategy)
|
|
14
18
|
@dir = Pathname(dir)
|
|
15
19
|
@umask = options[:umask] || File.umask
|
|
@@ -23,6 +27,7 @@ module Blobby
|
|
|
23
27
|
dir.directory? && dir.readable? && dir.writable?
|
|
24
28
|
end
|
|
25
29
|
|
|
30
|
+
# (see AbstractStore#[])
|
|
26
31
|
def [](key)
|
|
27
32
|
KeyConstraint.must_allow!(key)
|
|
28
33
|
relative_path = @sharding_strategy.call(key)
|
|
@@ -49,7 +54,7 @@ module Blobby
|
|
|
49
54
|
def read
|
|
50
55
|
@path.open("rb") do |io|
|
|
51
56
|
if block_given?
|
|
52
|
-
while chunk = io.read(512)
|
|
57
|
+
while (chunk = io.read(512))
|
|
53
58
|
yield chunk
|
|
54
59
|
end
|
|
55
60
|
nil
|
|
@@ -73,7 +78,8 @@ module Blobby
|
|
|
73
78
|
end
|
|
74
79
|
|
|
75
80
|
def delete
|
|
76
|
-
|
|
81
|
+
FileUtils.rm(@path)
|
|
82
|
+
true
|
|
77
83
|
rescue Errno::ENOENT
|
|
78
84
|
false
|
|
79
85
|
end
|
|
@@ -91,7 +97,7 @@ module Blobby
|
|
|
91
97
|
RAND_MAX = ("F" * 10).to_i(16)
|
|
92
98
|
|
|
93
99
|
def tmp_name
|
|
94
|
-
|
|
100
|
+
format("tmp-%X", rand(RAND_MAX))
|
|
95
101
|
end
|
|
96
102
|
|
|
97
103
|
def atomic_create(store_path)
|
|
@@ -102,7 +108,7 @@ module Blobby
|
|
|
102
108
|
begin
|
|
103
109
|
tmp = tmp_path.open(File::CREAT | File::EXCL | File::WRONLY, 0666)
|
|
104
110
|
tmp.binmode
|
|
105
|
-
rescue Errno::ENOENT
|
|
111
|
+
rescue Errno::ENOENT
|
|
106
112
|
FileUtils.mkdir_p(store_dir.to_s, :mode => apply_umask(0777))
|
|
107
113
|
retry
|
|
108
114
|
end
|
|
@@ -117,7 +123,7 @@ module Blobby
|
|
|
117
123
|
first_try = true
|
|
118
124
|
begin
|
|
119
125
|
tmp_path.rename(store_path)
|
|
120
|
-
rescue Errno::ESTALE
|
|
126
|
+
rescue Errno::ESTALE
|
|
121
127
|
raise unless first_try
|
|
122
128
|
first_try = false
|
|
123
129
|
now = Time.now
|
data/lib/blobby/http_store.rb
CHANGED
|
@@ -7,13 +7,18 @@ module Blobby
|
|
|
7
7
|
#
|
|
8
8
|
class HttpStore
|
|
9
9
|
|
|
10
|
-
def
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
def self.from_uri(uri)
|
|
11
|
+
new(uri)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def initialize(uri, options = {})
|
|
15
|
+
uri = URI(uri)
|
|
16
|
+
uri = URI("#{uri}/") unless uri.to_s.end_with?("/")
|
|
17
|
+
@base_uri = uri
|
|
13
18
|
@max_retries = options.fetch(:max_retries, 2)
|
|
14
19
|
end
|
|
15
20
|
|
|
16
|
-
attr_reader :
|
|
21
|
+
attr_reader :base_uri
|
|
17
22
|
attr_reader :max_retries
|
|
18
23
|
|
|
19
24
|
def available?
|
|
@@ -29,10 +34,6 @@ module Blobby
|
|
|
29
34
|
StoredObject.new(self, key)
|
|
30
35
|
end
|
|
31
36
|
|
|
32
|
-
def base_uri
|
|
33
|
-
URI(base_url)
|
|
34
|
-
end
|
|
35
|
-
|
|
36
37
|
def with_http_connection
|
|
37
38
|
remaining_retry_intervals = retry_intervals(max_retries)
|
|
38
39
|
begin
|
|
@@ -93,7 +94,11 @@ module Blobby
|
|
|
93
94
|
end
|
|
94
95
|
|
|
95
96
|
def write(content)
|
|
96
|
-
|
|
97
|
+
if content.respond_to?(:read)
|
|
98
|
+
content = content.read
|
|
99
|
+
else
|
|
100
|
+
content = content.dup
|
|
101
|
+
end
|
|
97
102
|
with_http_connection do |http, path|
|
|
98
103
|
put = Net::HTTP::Put.new(path)
|
|
99
104
|
put.body = content
|
|
@@ -6,6 +6,10 @@ module Blobby
|
|
|
6
6
|
#
|
|
7
7
|
class InMemoryStore
|
|
8
8
|
|
|
9
|
+
def self.from_uri(_uri)
|
|
10
|
+
new
|
|
11
|
+
end
|
|
12
|
+
|
|
9
13
|
def initialize(hash = {})
|
|
10
14
|
@hash = hash
|
|
11
15
|
end
|
|
@@ -54,7 +58,7 @@ module Blobby
|
|
|
54
58
|
end
|
|
55
59
|
|
|
56
60
|
def delete
|
|
57
|
-
|
|
61
|
+
!@hash.delete(key).nil?
|
|
58
62
|
end
|
|
59
63
|
|
|
60
64
|
end
|
|
@@ -8,8 +8,6 @@ module Blobby
|
|
|
8
8
|
#
|
|
9
9
|
module KeyConstraint
|
|
10
10
|
|
|
11
|
-
extend self
|
|
12
|
-
|
|
13
11
|
BAD_PATTERNS = [
|
|
14
12
|
%r{\A\Z}, # blank
|
|
15
13
|
%r{\A/}, # leading slash
|
|
@@ -18,6 +16,8 @@ module Blobby
|
|
|
18
16
|
%r{:} # colon
|
|
19
17
|
].freeze
|
|
20
18
|
|
|
19
|
+
module_function
|
|
20
|
+
|
|
21
21
|
def allows?(key)
|
|
22
22
|
BAD_PATTERNS.none? { |pattern| pattern =~ key } &&
|
|
23
23
|
URI.parse(key).path == key
|
data/lib/blobby/logging_store.rb
CHANGED
|
@@ -15,9 +15,10 @@ module Blobby
|
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
def [](key)
|
|
18
|
-
StoredObject.new(
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
StoredObject.new(
|
|
19
|
+
store[key],
|
|
20
|
+
:on_write => -> { logger.info(%(wrote to #{key.inspect} in #{store_name})) },
|
|
21
|
+
:on_delete => -> { logger.info(%(deleted #{key.inspect} from #{store_name})) }
|
|
21
22
|
)
|
|
22
23
|
end
|
|
23
24
|
|
data/lib/blobby/version.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
require "spec_helper"
|
|
2
2
|
|
|
3
3
|
require "blobby/filesystem_store"
|
|
4
4
|
require "blobby/store_behaviour"
|
|
@@ -38,11 +38,15 @@ describe Blobby::FilesystemStore do
|
|
|
38
38
|
describe "#write" do
|
|
39
39
|
|
|
40
40
|
it "writes to the file-system" do
|
|
41
|
-
expect
|
|
41
|
+
expect do
|
|
42
|
+
subject[key].write(content)
|
|
43
|
+
end.to change { expected_file_path.exist? }.from(false).to(true)
|
|
42
44
|
end
|
|
43
45
|
|
|
44
46
|
it "should have correct contents" do
|
|
45
|
-
expect
|
|
47
|
+
expect do
|
|
48
|
+
subject[key].write(content)
|
|
49
|
+
end.to change { File.read(expected_file_path) rescue nil }.from(nil).to(content)
|
|
46
50
|
end
|
|
47
51
|
|
|
48
52
|
it "retries if renaming throws an ESTALE" do
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
1
3
|
require "ostruct"
|
|
2
4
|
require "blobby/http_store"
|
|
3
5
|
require "blobby/in_memory_store"
|
|
@@ -41,9 +43,7 @@ describe Blobby::HttpStore do
|
|
|
41
43
|
|
|
42
44
|
def key
|
|
43
45
|
params[:captures].first.tap do |key|
|
|
44
|
-
if key =~ /FAIL/ # simulate failure
|
|
45
|
-
fail "hell"
|
|
46
|
-
end
|
|
46
|
+
fail "hell" if key =~ /FAIL/ # simulate failure
|
|
47
47
|
end
|
|
48
48
|
end
|
|
49
49
|
|
|
@@ -102,7 +102,7 @@ describe Blobby::HttpStore do
|
|
|
102
102
|
it "raises an exception" do
|
|
103
103
|
expect do
|
|
104
104
|
subject[key].read
|
|
105
|
-
end.to raise_error
|
|
105
|
+
end.to raise_error("hell")
|
|
106
106
|
end
|
|
107
107
|
|
|
108
108
|
end
|
|
@@ -112,7 +112,7 @@ describe Blobby::HttpStore do
|
|
|
112
112
|
it "raises an exception" do
|
|
113
113
|
expect do
|
|
114
114
|
subject[key].write("something")
|
|
115
|
-
end.to raise_error
|
|
115
|
+
end.to raise_error("hell")
|
|
116
116
|
end
|
|
117
117
|
|
|
118
118
|
end
|
|
@@ -179,7 +179,7 @@ describe Blobby::HttpStore do
|
|
|
179
179
|
|
|
180
180
|
end
|
|
181
181
|
|
|
182
|
-
context "when the
|
|
182
|
+
context "when the base_uri does not include a trailing slash" do
|
|
183
183
|
|
|
184
184
|
subject do
|
|
185
185
|
described_class.new("http://#{http_storage_host}/prefix")
|
|
@@ -191,7 +191,7 @@ describe Blobby::HttpStore do
|
|
|
191
191
|
|
|
192
192
|
end
|
|
193
193
|
|
|
194
|
-
context "when the
|
|
194
|
+
context "when the base_uri does include a trailing slash" do
|
|
195
195
|
|
|
196
196
|
subject do
|
|
197
197
|
described_class.new("http://#{http_storage_host}/prefix/")
|
|
@@ -203,4 +203,9 @@ describe Blobby::HttpStore do
|
|
|
203
203
|
|
|
204
204
|
end
|
|
205
205
|
|
|
206
|
+
it "can be created with a URI" do
|
|
207
|
+
store = described_class.new(URI("http://#{http_storage_host}/prefix/"))
|
|
208
|
+
expect(store.base_uri.to_s).to eq("http://#{http_storage_host}/prefix/")
|
|
209
|
+
end
|
|
210
|
+
|
|
206
211
|
end
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# encoding: UTF-8
|
|
2
2
|
|
|
3
|
+
require "spec_helper"
|
|
4
|
+
|
|
3
5
|
require "rspec"
|
|
4
6
|
|
|
5
7
|
module Blobby
|
|
@@ -98,7 +100,7 @@ shared_examples_for Blobby::Store do
|
|
|
98
100
|
|
|
99
101
|
context "for UTF-8 content" do
|
|
100
102
|
|
|
101
|
-
let(:content) { "SN☃WMAN" }
|
|
103
|
+
let(:content) { "SN☃WMAN".freeze }
|
|
102
104
|
|
|
103
105
|
before do
|
|
104
106
|
stored_object.write(content)
|
|
@@ -107,7 +109,9 @@ shared_examples_for Blobby::Store do
|
|
|
107
109
|
describe "#read" do
|
|
108
110
|
|
|
109
111
|
it "returns binary data" do
|
|
110
|
-
|
|
112
|
+
stored_content = stored_object.read
|
|
113
|
+
expect(stored_content.encoding.name).to eq("ASCII-8BIT")
|
|
114
|
+
expect(stored_content.force_encoding("UTF-8")).to eq(content)
|
|
111
115
|
end
|
|
112
116
|
|
|
113
117
|
end
|
data/spec/blobby_spec.rb
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
require "blobby"
|
|
4
|
+
|
|
5
|
+
describe Blobby do
|
|
6
|
+
|
|
7
|
+
describe ".store" do
|
|
8
|
+
|
|
9
|
+
context "with an absolute file path" do
|
|
10
|
+
|
|
11
|
+
it "creates a FilesystemStore" do
|
|
12
|
+
store = Blobby.store("/data")
|
|
13
|
+
expect(store).to be_a(Blobby::FilesystemStore)
|
|
14
|
+
expect(store.dir.to_s).to eq("/data")
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
context "with a file:// URI" do
|
|
20
|
+
|
|
21
|
+
it "creates a FilesystemStore" do
|
|
22
|
+
store = Blobby.store("file:///data")
|
|
23
|
+
expect(store).to be_a(Blobby::FilesystemStore)
|
|
24
|
+
expect(store.dir.to_s).to eq("/data")
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
context "with an http:// URI" do
|
|
30
|
+
|
|
31
|
+
it "creates a HttpStore" do
|
|
32
|
+
store = Blobby.store("http://storage.com/data/")
|
|
33
|
+
expect(store).to be_a(Blobby::HttpStore)
|
|
34
|
+
expect(store.base_uri.host).to eq("storage.com")
|
|
35
|
+
expect(store.base_uri.path).to eq("/data/")
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
context "with an https:// URI" do
|
|
41
|
+
|
|
42
|
+
it "creates a HttpStore" do
|
|
43
|
+
store = Blobby.store("https://storage.com/data/")
|
|
44
|
+
expect(store).to be_a(Blobby::HttpStore)
|
|
45
|
+
expect(store.base_uri.scheme).to eq("https")
|
|
46
|
+
expect(store.base_uri.host).to eq("storage.com")
|
|
47
|
+
expect(store.base_uri.path).to eq("/data/")
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
context "with 'in-memory:/'" do
|
|
53
|
+
|
|
54
|
+
it "creates an InMemoryStore" do
|
|
55
|
+
store = Blobby.store("in-memory:/")
|
|
56
|
+
expect(store).to be_a(Blobby::InMemoryStore)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
end
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ENV["RACK_ENV"] = "test"
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: blobby
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.0
|
|
4
|
+
version: 1.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Mike Williams
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2016-05-22 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description:
|
|
14
14
|
email:
|
|
@@ -21,10 +21,13 @@ files:
|
|
|
21
21
|
- ".rspec"
|
|
22
22
|
- ".rubocop.yml"
|
|
23
23
|
- ".travis.yml"
|
|
24
|
+
- CHANGES.md
|
|
24
25
|
- Gemfile
|
|
25
26
|
- README.md
|
|
26
27
|
- Rakefile
|
|
27
28
|
- blobby.gemspec
|
|
29
|
+
- lib/blobby.rb
|
|
30
|
+
- lib/blobby/abstract_store.rb
|
|
28
31
|
- lib/blobby/composite_store.rb
|
|
29
32
|
- lib/blobby/fake_success_store.rb
|
|
30
33
|
- lib/blobby/filesystem_store.rb
|
|
@@ -43,6 +46,8 @@ files:
|
|
|
43
46
|
- spec/blobby/key_transforming_store_spec.rb
|
|
44
47
|
- spec/blobby/logging_store_spec.rb
|
|
45
48
|
- spec/blobby/store_behaviour.rb
|
|
49
|
+
- spec/blobby_spec.rb
|
|
50
|
+
- spec/spec_helper.rb
|
|
46
51
|
homepage: https://github.com/realestate-com-au/blobby
|
|
47
52
|
licenses: []
|
|
48
53
|
metadata: {}
|
|
@@ -62,7 +67,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
62
67
|
version: '0'
|
|
63
68
|
requirements: []
|
|
64
69
|
rubyforge_project:
|
|
65
|
-
rubygems_version: 2.
|
|
70
|
+
rubygems_version: 2.5.1
|
|
66
71
|
signing_key:
|
|
67
72
|
specification_version: 4
|
|
68
73
|
summary: Various ways of storing BLOBs
|
|
@@ -75,3 +80,5 @@ test_files:
|
|
|
75
80
|
- spec/blobby/key_transforming_store_spec.rb
|
|
76
81
|
- spec/blobby/logging_store_spec.rb
|
|
77
82
|
- spec/blobby/store_behaviour.rb
|
|
83
|
+
- spec/blobby_spec.rb
|
|
84
|
+
- spec/spec_helper.rb
|