moped-gridfs 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,29 @@
1
+ require "moped/gridfs/bucketable"
2
+ require "moped/gridfs/file"
3
+
4
+ module Moped
5
+ module GridFS
6
+ class Files
7
+ include Enumerable
8
+ include Bucketable
9
+
10
+ attr_reader :bucket
11
+
12
+ def initialize(bucket)
13
+ @bucket = bucket
14
+ end
15
+
16
+ def [](id)
17
+ bucket.open(id, 'r')
18
+ end
19
+
20
+ def count
21
+ files_collection.find.count
22
+ end
23
+
24
+ def each(&block)
25
+ files_collection.find.each { |document| yield(self[document['_id']]) }
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,15 @@
1
+ module Moped
2
+ module GridFS
3
+ module Inspectable
4
+
5
+ private
6
+
7
+ def build_inspect_string(hash)
8
+ memaddr = (__send__(:object_id) << 1).to_s(16)
9
+ string = "#<#{self.class.name}:#{memaddr}"
10
+ hash.each { |k, v| string << " #{k}=#{v}" }
11
+ string << ">"
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,5 @@
1
+ module Moped
2
+ module GridFS
3
+ VERSION = "1.0.0"
4
+ end
5
+ end
@@ -0,0 +1,26 @@
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'moped/gridfs/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "moped-gridfs"
7
+ spec.version = Moped::GridFS::VERSION
8
+ spec.authors = ["topac"]
9
+ spec.email = ["dani.m.mobile@gmail.com"]
10
+ spec.summary = %q{mongoDB GridFS implementation for Moped}
11
+ spec.description = %q{mongoDB GridFS implementation for Moped}
12
+ spec.homepage = "https://www.github.com/topac/moped-gridfs"
13
+ spec.license = "MIT"
14
+
15
+ spec.files = `git ls-files -z`.split("\x0")
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_dependency("moped")
21
+
22
+ spec.add_development_dependency("bundler", "~> 1.6")
23
+ spec.add_development_dependency("rake")
24
+ spec.add_development_dependency("rspec")
25
+ spec.add_development_dependency("pry")
26
+ end
data/perf/compare.rb ADDED
@@ -0,0 +1,143 @@
1
+ # Compare with mongo-ruby-driver
2
+ # $ gem install mongo
3
+ # $ gem install bson_ext
4
+
5
+ $INCLUDE_MONGO = true
6
+
7
+ require_relative 'perf_helper'
8
+
9
+ def reset
10
+ purge
11
+
12
+ @bucket = moped_session.bucket
13
+ @grid = Mongo::GridFileSystem.new(mongo_connection)
14
+ end
15
+
16
+ def content(size = 0.5) # 0.5 mb
17
+ "\xDF\x00\xAB\xFA" * (1024 * 1024 * size)
18
+ end
19
+
20
+ profile("Create an empty file", n: [1000, 5_000]) do |bm, n|
21
+ reset
22
+
23
+ bm.report do
24
+ n.times { |i| @bucket.open("file#{i}", 'w') }
25
+ end
26
+
27
+ reset
28
+
29
+ bm.report do
30
+ n.times { |i| @grid.open( "file#{i}", 'w').close }
31
+ end
32
+ end
33
+
34
+ profile("Create and write a file", n: [10, 100]) do |bm, n|
35
+ reset
36
+
37
+ bm.report do
38
+ n.times { |i| @bucket.open("file#{i}", 'w').write(content) }
39
+ end
40
+
41
+ reset
42
+
43
+ bm.report do
44
+ n.times do |i|
45
+ file = @grid.open("file", "w")
46
+ file.write(content)
47
+ file.close
48
+ end
49
+ end
50
+ end
51
+
52
+ profile("Sequentially write on a file", n: [1000, 5_000]) do |bm, n|
53
+ reset
54
+ file = @bucket.open("file", 'w')
55
+
56
+ bm.report do
57
+ n.times { |i| file.write("foobar") }
58
+ end
59
+
60
+ reset
61
+ file = @grid.open("file", "w")
62
+
63
+ bm.report do
64
+ (n-1).times { |i| file.write("foobar") }
65
+ file.close
66
+ end
67
+ end
68
+
69
+ profile("Open a file in r mode", n: [1000, 5_000]) do |bm, n|
70
+ reset
71
+ @bucket.open("file", 'w')
72
+
73
+ bm.report do
74
+ n.times { |i| @bucket.open("file", "r") }
75
+ end
76
+
77
+ reset
78
+ @grid.open("file", 'w').close
79
+
80
+ bm.report do
81
+ n.times { |i| @grid.open("file", "r") }
82
+ end
83
+ end
84
+
85
+ profile("Open a file in w mode", n: [1000, 5_000]) do |bm, n|
86
+ reset
87
+
88
+ bm.report do
89
+ n.times { |i| @bucket.open("file", "w") }
90
+ end
91
+
92
+ reset
93
+
94
+ bm.report do
95
+ n.times { |i| @grid.open("file", "w") }
96
+ end
97
+ end
98
+
99
+ def write_sample_file(klass)
100
+ file = klass.open("file", 'w')
101
+ file.write(content)
102
+ file.close if file.respond_to?(:close)
103
+
104
+ klass.open("file", "r")
105
+ end
106
+
107
+ profile("Read a whole file from the beginning", n: 100) do |bm, n|
108
+ reset
109
+ file = write_sample_file(@bucket)
110
+
111
+ bm.report do
112
+ n.times { |i| file.seek(0); file.read }
113
+ end
114
+
115
+ reset
116
+ file = write_sample_file(@grid)
117
+
118
+ bm.report do
119
+ n.times { |i| file.seek(0); file.read }
120
+ end
121
+ end
122
+
123
+ profile("Read 100 bytes a time till the end", n: [10, 100]) do |bm, n|
124
+ reset
125
+ file = write_sample_file(@bucket)
126
+
127
+ bm.report do
128
+ n.times do |i|
129
+ file.seek(0)
130
+ while !file.eof?; file.read(100); end
131
+ end
132
+ end
133
+
134
+ reset
135
+ file = write_sample_file(@grid)
136
+
137
+ bm.report do
138
+ n.times do |i|
139
+ file.seek(0)
140
+ while !file.eof?; file.read(100); end
141
+ end
142
+ end
143
+ end
@@ -0,0 +1,33 @@
1
+ require 'benchmark'
2
+ require_relative '../spec/spec_helper'
3
+
4
+ if $INCLUDE_MONGO
5
+ require 'mongo'
6
+
7
+ def mongo_connection
8
+ client = Mongo::MongoClient.new(ENV["MOPED-GRIDFS_SPEC_HOST"], ENV["MOPED-GRIDFS_SPEC_PORT"])
9
+ client[ENV["MOPED-GRIDFS_SPEC_DB"]]
10
+ end
11
+
12
+ module Mongo
13
+ class GridIO
14
+ def warn(*args); end
15
+ end
16
+ end
17
+ end
18
+
19
+ def purge
20
+ drop_all_collections
21
+ end
22
+
23
+ def profile(message, options = {})
24
+ ary = [options[:n] || 1].flatten
25
+
26
+ ary.each do |n|
27
+ puts message+" (#{n} times)"
28
+
29
+ Benchmark.bm do |bm|
30
+ yield(bm, n)
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,119 @@
1
+ require 'spec_helper'
2
+ require 'moped/gridfs/bucket'
3
+
4
+ describe Moped::GridFS::Bucket do
5
+
6
+ let(:session) { moped_session }
7
+
8
+ describe '#initialize' do
9
+
10
+ context 'when the given name is empty' do
11
+
12
+ it 'raises an error' do
13
+ expect { described_class.new(session, '') }.to raise_error
14
+ end
15
+ end
16
+
17
+ context 'when the given name is nil' do
18
+
19
+ it 'raises an error' do
20
+ expect { described_class.new(session, nil) }.to raise_error
21
+ end
22
+ end
23
+
24
+ context 'when the given name is not empty nor nil' do
25
+
26
+ it 'does not raise any error' do
27
+ expect { described_class.new(session, 'foo') }.not_to raise_error
28
+ end
29
+ end
30
+ end
31
+
32
+ let(:subject) { described_class.new(session, 'bar') }
33
+
34
+ describe '#files' do
35
+
36
+ it 'returns an enumerable' do
37
+ expect(subject.files).to respond_to(:each)
38
+ end
39
+ end
40
+
41
+ describe '#drop' do
42
+
43
+ before do
44
+ subject.files_collection.insert(foo: 'bar')
45
+ subject.chunks_collection.insert(foo: 'bar')
46
+ end
47
+
48
+ it 'drops the two collections' do
49
+ subject.drop
50
+
51
+ expect(subject.files_collection.find.count).to eq(0)
52
+ expect(subject.chunks_collection.find.count).to eq(0)
53
+ end
54
+ end
55
+
56
+ describe '#delete' do
57
+
58
+ context 'when a file is missing' do
59
+
60
+ it 'returns nil' do
61
+ expect(subject.delete("file")).to be_nil
62
+ end
63
+ end
64
+
65
+ context 'when a file exists' do
66
+
67
+ before do
68
+ subject.open("file", "w").write("buffer")
69
+ end
70
+
71
+ it 'not to returns nil' do
72
+ expect(subject.delete("file")).not_to be_nil
73
+ end
74
+
75
+ it 'deletes the file' do
76
+ subject.delete("file")
77
+ expect { subject.open("foo", "r") }.to raise_error
78
+ end
79
+ end
80
+ end
81
+
82
+ describe '#open' do
83
+
84
+ context 'when the mode is w' do
85
+
86
+ it 'returns a writable file' do
87
+ expect(subject.open("foo", "w")).to be_writable
88
+ end
89
+ end
90
+
91
+ context 'when the mode is r' do
92
+
93
+ context 'and the file is missing' do
94
+
95
+ it 'raises an error' do
96
+ expect { subject.open("foo", "r") }.to raise_error
97
+ end
98
+ end
99
+
100
+ context 'and the file exists' do
101
+
102
+ before do
103
+ subject.open("bar", "w").write("buffer")
104
+ end
105
+
106
+ it 'returns a readable file' do
107
+ expect(subject.open("bar", "r")).to be_readable
108
+ end
109
+ end
110
+ end
111
+
112
+ context 'when the mode is a' do
113
+
114
+ it 'returns a writable file' do
115
+ expect(subject.open("foo", "a")).to be_writable
116
+ end
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+ require 'moped/gridfs/buckets'
3
+
4
+ describe Moped::GridFS::Buckets do
5
+
6
+ let(:session) { moped_session }
7
+
8
+ let(:subject) { described_class.new(session) }
9
+
10
+ before do
11
+ Moped::GridFS::Bucket.new(session, "bar").open("file", "w")
12
+ Moped::GridFS::Bucket.new(session, "foo").open("file", "w")
13
+ end
14
+
15
+ describe '#names' do
16
+
17
+ it 'returns the bucket names' do
18
+ expect(subject.names.sort).to eq(%w[bar foo])
19
+ end
20
+ end
21
+
22
+ describe '#count' do
23
+
24
+ it 'returns the buckets count' do
25
+ expect(subject.count).to eq(2)
26
+ end
27
+ end
28
+
29
+ describe '#[]' do
30
+
31
+ it 'returns a bucket with the given name' do
32
+ bucket = subject['test']
33
+ expect(bucket.name).to eq('test')
34
+ end
35
+ end
36
+
37
+ describe '#each' do
38
+
39
+ it 'iterates over the buckets' do
40
+ names = []
41
+ subject.each { |bucket| names << bucket.name }
42
+ expect(names.sort).to eq(%w[bar foo])
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,83 @@
1
+ require 'spec_helper'
2
+ require 'moped/gridfs/file'
3
+
4
+ require_relative 'write'
5
+ require_relative 'read'
6
+ require_relative 'getters'
7
+ require_relative 'setters'
8
+
9
+ describe Moped::GridFS::File do
10
+
11
+ $chunk_size = 5
12
+
13
+ before do
14
+ described_class.any_instance.stub(:default_chunk_size).and_return($chunk_size)
15
+ end
16
+
17
+ let(:session) { moped_session }
18
+
19
+ let(:bucket) { session.bucket }
20
+
21
+ context 'when mode is r' do
22
+
23
+ let(:access_mode) { 'r' }
24
+
25
+ include_examples :read, :getters
26
+
27
+ let(:file) do
28
+ bucket.open("file", "w").write("foobar")
29
+ bucket.open("file", access_mode)
30
+ end
31
+
32
+ it 'cannot be written' do
33
+ expect { file.write("foo") }.to raise_error
34
+ end
35
+
36
+ it 'does not have setters' do
37
+ %w[content_type metadata aliases filename upload_date].each do |name|
38
+ expect(file).not_to respond_to(:"#{name}=")
39
+ end
40
+ end
41
+ end
42
+
43
+ context 'when mode is r+' do
44
+
45
+ let(:access_mode) { 'r+' }
46
+
47
+ include_examples :read, :getters, :setters
48
+ end
49
+
50
+ context 'when mode is w' do
51
+
52
+ let(:access_mode) { 'w' }
53
+
54
+ include_examples :write, :getters, :setters
55
+
56
+ it 'cannot be readed' do
57
+ bucket.open("file", "w").write("foobar")
58
+ file = bucket.open("file", access_mode)
59
+ expect { file.read }.to raise_error
60
+ end
61
+ end
62
+
63
+ context 'when mode is w+' do
64
+
65
+ let(:access_mode) { 'w+' }
66
+
67
+ include_examples :write, :getters, :setters
68
+ end
69
+
70
+ context 'when mode is a' do
71
+
72
+ let(:access_mode) { 'a' }
73
+
74
+ include_examples :write, :getters, :setters
75
+ end
76
+
77
+ context 'when mode is a+' do
78
+
79
+ let(:access_mode) { 'a+' }
80
+
81
+ include_examples :write, :read, :getters, :setters
82
+ end
83
+ end