mongoid-grid_fs 1.2.0 → 1.3.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.
- data/Rakefile +1 -1
- data/lib/mongoid-grid_fs.rb +373 -372
- data/mongoid-grid_fs.gemspec +3 -3
- data/test/mongoid-grid_fs_test.rb +5 -1
- metadata +6 -6
data/Rakefile
CHANGED
data/lib/mongoid-grid_fs.rb
CHANGED
@@ -1,492 +1,493 @@
|
|
1
1
|
##
|
2
2
|
#
|
3
|
-
|
4
|
-
|
3
|
+
module Mongoid
|
4
|
+
class GridFS
|
5
|
+
const_set :Version, '1.3.0'
|
5
6
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
7
|
+
class << GridFS
|
8
|
+
def version
|
9
|
+
const_get :Version
|
10
|
+
end
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
12
|
+
def dependencies
|
13
|
+
{
|
14
|
+
'mongoid' => [ 'mongoid' , '~> 3.0.1' ] ,
|
15
|
+
'mime/types' => [ 'mime-types' , '~> 1.19' ] ,
|
16
|
+
}
|
17
|
+
end
|
17
18
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
19
|
+
def libdir(*args, &block)
|
20
|
+
@libdir ||= File.expand_path(__FILE__).sub(/\.rb$/,'')
|
21
|
+
args.empty? ? @libdir : File.join(@libdir, *args)
|
22
|
+
ensure
|
23
|
+
if block
|
24
|
+
begin
|
25
|
+
$LOAD_PATH.unshift(@libdir)
|
26
|
+
block.call()
|
27
|
+
ensure
|
28
|
+
$LOAD_PATH.shift()
|
29
|
+
end
|
28
30
|
end
|
29
31
|
end
|
30
|
-
end
|
31
32
|
|
32
|
-
|
33
|
-
|
34
|
-
|
33
|
+
def load(*libs)
|
34
|
+
libs = libs.join(' ').scan(/[^\s+]+/)
|
35
|
+
libdir{ libs.each{|lib| Kernel.load(lib) } }
|
36
|
+
end
|
35
37
|
end
|
36
|
-
end
|
37
38
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
end
|
43
|
-
|
44
|
-
if defined?(gem)
|
45
|
-
dependencies.each do |lib, dependency|
|
46
|
-
gem(*dependency)
|
47
|
-
require(lib)
|
39
|
+
begin
|
40
|
+
require 'rubygems'
|
41
|
+
rescue LoadError
|
42
|
+
nil
|
48
43
|
end
|
49
|
-
end
|
50
44
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
##
|
56
|
-
#
|
57
|
-
class GridFS
|
58
|
-
class << GridFS
|
59
|
-
attr_accessor :namespace
|
60
|
-
attr_accessor :file_model
|
61
|
-
attr_accessor :chunk_model
|
62
|
-
|
63
|
-
def init!
|
64
|
-
GridFS.build_namespace_for(:Fs)
|
65
|
-
|
66
|
-
GridFS.namespace = Fs
|
67
|
-
GridFS.file_model = Fs.file_model
|
68
|
-
GridFS.chunk_model = Fs.chunk_model
|
69
|
-
|
70
|
-
const_set(:File, Fs.file_model)
|
71
|
-
const_set(:Chunk, Fs.chunk_model)
|
72
|
-
|
73
|
-
to_delegate = %w(
|
74
|
-
put
|
75
|
-
get
|
76
|
-
delete
|
77
|
-
find
|
78
|
-
[]
|
79
|
-
[]=
|
80
|
-
clear
|
81
|
-
)
|
82
|
-
|
83
|
-
to_delegate.each do |method|
|
84
|
-
class_eval <<-__
|
85
|
-
def GridFS.#{ method }(*args, &block)
|
86
|
-
::GridFS::Fs::#{ method }(*args, &block)
|
87
|
-
end
|
88
|
-
__
|
45
|
+
if defined?(gem)
|
46
|
+
dependencies.each do |lib, dependency|
|
47
|
+
gem(*dependency)
|
48
|
+
require(lib)
|
89
49
|
end
|
90
50
|
end
|
91
|
-
end
|
92
51
|
|
93
|
-
|
94
|
-
|
95
|
-
def GridFS.namespace_for(prefix)
|
96
|
-
prefix = prefix.to_s.downcase
|
97
|
-
const = "::GridFS::#{ prefix.to_s.camelize }"
|
98
|
-
namespace = const.split(/::/).last
|
99
|
-
const_defined?(namespace) ? const_get(namespace) : build_namespace_for(namespace)
|
52
|
+
require "digest/md5"
|
53
|
+
require "cgi"
|
100
54
|
end
|
55
|
+
end
|
101
56
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
57
|
+
##
|
58
|
+
#
|
59
|
+
module Mongoid
|
60
|
+
class GridFS
|
61
|
+
class << GridFS
|
62
|
+
attr_accessor :namespace
|
63
|
+
attr_accessor :file_model
|
64
|
+
attr_accessor :chunk_model
|
107
65
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
66
|
+
def init!
|
67
|
+
GridFS.build_namespace_for(:Fs)
|
68
|
+
|
69
|
+
GridFS.namespace = Fs
|
70
|
+
GridFS.file_model = Fs.file_model
|
71
|
+
GridFS.chunk_model = Fs.chunk_model
|
72
|
+
|
73
|
+
const_set(:File, Fs.file_model)
|
74
|
+
const_set(:Chunk, Fs.chunk_model)
|
75
|
+
|
76
|
+
to_delegate = %w(
|
77
|
+
put
|
78
|
+
get
|
79
|
+
delete
|
80
|
+
find
|
81
|
+
[]
|
82
|
+
[]=
|
83
|
+
clear
|
84
|
+
)
|
85
|
+
|
86
|
+
to_delegate.each do |method|
|
87
|
+
class_eval <<-__
|
88
|
+
def GridFS.#{ method }(*args, &block)
|
89
|
+
::GridFS::Fs::#{ method }(*args, &block)
|
90
|
+
end
|
91
|
+
__
|
92
|
+
end
|
112
93
|
end
|
94
|
+
end
|
113
95
|
|
114
|
-
|
96
|
+
##
|
97
|
+
#
|
98
|
+
def GridFS.namespace_for(prefix)
|
99
|
+
prefix = prefix.to_s.downcase
|
100
|
+
const = "::GridFS::#{ prefix.to_s.camelize }"
|
101
|
+
namespace = const.split(/::/).last
|
102
|
+
const_defined?(namespace) ? const_get(namespace) : build_namespace_for(namespace)
|
103
|
+
end
|
115
104
|
|
116
|
-
|
117
|
-
|
105
|
+
##
|
106
|
+
#
|
107
|
+
def GridFS.build_namespace_for(prefix)
|
108
|
+
prefix = prefix.to_s.downcase
|
109
|
+
const = prefix.camelize
|
118
110
|
|
119
|
-
|
120
|
-
|
111
|
+
namespace =
|
112
|
+
Module.new do
|
113
|
+
module_eval(&NamespaceMixin)
|
114
|
+
self
|
115
|
+
end
|
121
116
|
|
122
|
-
|
123
|
-
chunk_model.file_model = file_model
|
117
|
+
const_set(const, namespace)
|
124
118
|
|
125
|
-
|
126
|
-
|
127
|
-
namespace.chunk_model = chunk_model
|
119
|
+
file_model = build_file_model_for(namespace)
|
120
|
+
chunk_model = build_chunk_model_for(namespace)
|
128
121
|
|
129
|
-
|
130
|
-
|
122
|
+
file_model.namespace = namespace
|
123
|
+
chunk_model.namespace = namespace
|
131
124
|
|
132
|
-
|
133
|
-
|
125
|
+
file_model.chunk_model = chunk_model
|
126
|
+
chunk_model.file_model = file_model
|
134
127
|
|
135
|
-
|
136
|
-
|
128
|
+
namespace.prefix = prefix
|
129
|
+
namespace.file_model = file_model
|
130
|
+
namespace.chunk_model = chunk_model
|
137
131
|
|
138
|
-
|
139
|
-
|
140
|
-
attr_accessor :prefix
|
141
|
-
attr_accessor :file_model
|
142
|
-
attr_accessor :chunk_model
|
132
|
+
namespace.send(:const_set, :File, file_model)
|
133
|
+
namespace.send(:const_set, :Chunk, chunk_model)
|
143
134
|
|
144
|
-
|
145
|
-
|
146
|
-
end
|
135
|
+
#at_exit{ file_model.create_indexes rescue nil }
|
136
|
+
#at_exit{ chunk_model.create_indexes rescue nil }
|
147
137
|
|
148
|
-
|
149
|
-
|
150
|
-
end
|
138
|
+
const_get(const)
|
139
|
+
end
|
151
140
|
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
141
|
+
NamespaceMixin = proc do
|
142
|
+
class << self
|
143
|
+
attr_accessor :prefix
|
144
|
+
attr_accessor :file_model
|
145
|
+
attr_accessor :chunk_model
|
156
146
|
|
157
|
-
|
158
|
-
|
147
|
+
def to_s
|
148
|
+
prefix
|
159
149
|
end
|
160
150
|
|
161
|
-
|
162
|
-
|
151
|
+
def namespace
|
152
|
+
prefix
|
163
153
|
end
|
164
154
|
|
165
|
-
|
166
|
-
|
167
|
-
|
155
|
+
def put(readable, attributes = {})
|
156
|
+
chunks = []
|
157
|
+
file = file_model.new
|
158
|
+
attributes.to_options!
|
168
159
|
|
169
|
-
|
170
|
-
|
171
|
-
|
160
|
+
if attributes.has_key?(:id)
|
161
|
+
file.id = attributes.delete(:id)
|
162
|
+
end
|
172
163
|
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
n = 0
|
164
|
+
if attributes.has_key?(:_id)
|
165
|
+
file.id = attributes.delete(:_id)
|
166
|
+
end
|
177
167
|
|
178
|
-
|
168
|
+
if attributes.has_key?(:content_type)
|
169
|
+
attributes[:contentType] = attributes.delete(:content_type)
|
170
|
+
end
|
179
171
|
|
180
|
-
|
181
|
-
attributes[:
|
182
|
-
|
172
|
+
if attributes.has_key?(:upload_date)
|
173
|
+
attributes[:uploadDate] = attributes.delete(:upload_date)
|
174
|
+
end
|
183
175
|
|
184
|
-
|
185
|
-
|
186
|
-
|
176
|
+
md5 = Digest::MD5.new
|
177
|
+
length = 0
|
178
|
+
chunkSize = file.chunkSize
|
179
|
+
n = 0
|
187
180
|
|
188
|
-
GridFS.
|
189
|
-
md5 << buf
|
190
|
-
length += buf.size
|
191
|
-
chunk = file.chunks.build
|
192
|
-
chunk.data = binary_for(buf)
|
193
|
-
chunk.n = n
|
194
|
-
n += 1
|
195
|
-
chunk.save!
|
196
|
-
chunks.push(chunk)
|
197
|
-
end
|
181
|
+
GridFS.reading(readable) do |io|
|
198
182
|
|
199
|
-
|
183
|
+
filename =
|
184
|
+
attributes[:filename] ||=
|
185
|
+
[file.id.to_s, GridFS.extract_basename(io)].join('/').squeeze('/')
|
200
186
|
|
201
|
-
|
202
|
-
|
203
|
-
|
187
|
+
content_type =
|
188
|
+
attributes[:contentType] ||=
|
189
|
+
GridFS.extract_content_type(filename) || file.contentType
|
204
190
|
|
205
|
-
|
191
|
+
GridFS.chunking(io, chunkSize) do |buf|
|
192
|
+
md5 << buf
|
193
|
+
length += buf.size
|
194
|
+
chunk = file.chunks.build
|
195
|
+
chunk.data = binary_for(buf)
|
196
|
+
chunk.n = n
|
197
|
+
n += 1
|
198
|
+
chunk.save!
|
199
|
+
chunks.push(chunk)
|
200
|
+
end
|
206
201
|
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
202
|
+
end
|
203
|
+
|
204
|
+
attributes[:length] ||= length
|
205
|
+
attributes[:uploadDate] ||= Time.now.utc
|
206
|
+
attributes[:md5] ||= md5.hexdigest
|
207
|
+
|
208
|
+
file.update_attributes(attributes)
|
212
209
|
|
213
|
-
|
214
|
-
|
215
|
-
|
210
|
+
file.save!
|
211
|
+
file
|
212
|
+
ensure
|
213
|
+
chunks.each{|chunk| chunk.destroy rescue nil} if $!
|
216
214
|
end
|
217
|
-
|
218
|
-
|
219
|
-
|
215
|
+
|
216
|
+
if defined?(Moped)
|
217
|
+
def binary_for(*buf)
|
218
|
+
Moped::BSON::Binary.new(:generic, buf.join)
|
219
|
+
end
|
220
|
+
else
|
221
|
+
def binary_for(buf)
|
222
|
+
BSON::Binary.new(buf.bytes.to_a)
|
223
|
+
end
|
220
224
|
end
|
221
|
-
end
|
222
225
|
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
+
def get(id)
|
227
|
+
file_model.find(id)
|
228
|
+
end
|
226
229
|
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
230
|
+
def delete(id)
|
231
|
+
file_model.find(id).destroy
|
232
|
+
rescue
|
233
|
+
nil
|
234
|
+
end
|
232
235
|
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
236
|
+
def where(conditions = {})
|
237
|
+
case conditions
|
238
|
+
when String
|
239
|
+
file_model.where(:filename => conditions)
|
240
|
+
else
|
241
|
+
file_model.where(conditions)
|
242
|
+
end
|
239
243
|
end
|
240
|
-
end
|
241
244
|
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
+
def find(*args)
|
246
|
+
where(*args).first
|
247
|
+
end
|
245
248
|
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
+
def [](filename)
|
250
|
+
file_model.where(:filename => filename.to_s).first
|
251
|
+
end
|
249
252
|
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
253
|
+
def []=(filename, readable)
|
254
|
+
file = self[filename]
|
255
|
+
file.destroy if file
|
256
|
+
put(readable, :filename => filename.to_s)
|
257
|
+
end
|
255
258
|
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
+
def clear
|
260
|
+
file_model.destroy_all
|
261
|
+
end
|
259
262
|
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
263
|
+
# TODO - opening with a mode = 'w' should return a GridIO::IOProxy
|
264
|
+
# implementing a StringIO-like interface
|
265
|
+
#
|
266
|
+
def open(filename, mode = 'r', &block)
|
267
|
+
raise NotImplementedError
|
268
|
+
end
|
265
269
|
end
|
266
270
|
end
|
267
|
-
end
|
268
271
|
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
272
|
+
##
|
273
|
+
#
|
274
|
+
def GridFS.build_file_model_for(namespace)
|
275
|
+
prefix = namespace.name.split(/::/).last.downcase
|
276
|
+
file_model_name = "#{ namespace.name }::File"
|
277
|
+
chunk_model_name = "#{ namespace.name }::Chunk"
|
275
278
|
|
276
|
-
|
277
|
-
|
279
|
+
Class.new do
|
280
|
+
include Mongoid::Document
|
278
281
|
|
279
|
-
|
282
|
+
singleton_class = class << self; self; end
|
280
283
|
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
284
|
+
singleton_class.instance_eval do
|
285
|
+
define_method(:name){ file_model_name }
|
286
|
+
attr_accessor :chunk_model
|
287
|
+
attr_accessor :namespace
|
288
|
+
end
|
286
289
|
|
287
|
-
|
290
|
+
self.default_collection_name = "#{ prefix }.files"
|
288
291
|
|
289
|
-
|
290
|
-
|
292
|
+
field(:filename, :type => String)
|
293
|
+
field(:contentType, :type => String, :default => 'application/octet-stream')
|
291
294
|
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
295
|
+
field(:length, :type => Integer, :default => 0)
|
296
|
+
field(:chunkSize, :type => Integer, :default => (256 * (2 ** 20)))
|
297
|
+
field(:uploadDate, :type => Date, :default => Time.now.utc)
|
298
|
+
field(:md5, :type => String, :default => Digest::MD5.hexdigest(''))
|
296
299
|
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
300
|
+
%w( filename contentType length chunkSize uploadDate md5 ).each do |f|
|
301
|
+
validates_presence_of(f)
|
302
|
+
end
|
303
|
+
validates_uniqueness_of(:filename)
|
301
304
|
|
302
|
-
|
305
|
+
has_many(:chunks, :class_name => chunk_model_name, :inverse_of => :files, :dependent => :destroy, :order => [:n, :asc])
|
303
306
|
|
304
|
-
|
307
|
+
index({:filename => 1}, :unique => true)
|
305
308
|
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
+
def path
|
310
|
+
filename
|
311
|
+
end
|
309
312
|
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
+
def basename
|
314
|
+
::File.basename(filename)
|
315
|
+
end
|
313
316
|
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
+
def prefix
|
318
|
+
self.class.namespace.prefix
|
319
|
+
end
|
317
320
|
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
+
def each(&block)
|
322
|
+
chunks.all.order_by([:n, :asc]).each do |chunk|
|
323
|
+
block.call(chunk.to_s)
|
324
|
+
end
|
321
325
|
end
|
322
|
-
end
|
323
326
|
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
327
|
+
def data
|
328
|
+
data = ''
|
329
|
+
each{|chunk| data << chunk}
|
330
|
+
data
|
331
|
+
end
|
329
332
|
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
+
def base64
|
334
|
+
Array(to_s).pack('m')
|
335
|
+
end
|
333
336
|
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
337
|
+
def data_uri(options = {})
|
338
|
+
data = base64.chomp
|
339
|
+
"data:#{ content_type };base64,".concat(data)
|
340
|
+
end
|
338
341
|
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
342
|
+
def bytes(&block)
|
343
|
+
if block
|
344
|
+
each{|data| block.call(data)}
|
345
|
+
length
|
346
|
+
else
|
347
|
+
bytes = []
|
348
|
+
each{|data| bytes.push(*data)}
|
349
|
+
bytes
|
350
|
+
end
|
347
351
|
end
|
348
|
-
end
|
349
352
|
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
+
def close
|
354
|
+
self
|
355
|
+
end
|
353
356
|
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
+
def content_type
|
358
|
+
contentType
|
359
|
+
end
|
357
360
|
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
+
def update_date
|
362
|
+
updateDate
|
363
|
+
end
|
361
364
|
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
+
def created_at
|
366
|
+
updateDate
|
367
|
+
end
|
365
368
|
|
366
|
-
|
367
|
-
|
369
|
+
def namespace
|
370
|
+
self.class.namespace
|
371
|
+
end
|
368
372
|
end
|
369
373
|
end
|
370
|
-
end
|
371
374
|
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
375
|
+
##
|
376
|
+
#
|
377
|
+
def GridFS.build_chunk_model_for(namespace)
|
378
|
+
prefix = namespace.name.split(/::/).last.downcase
|
379
|
+
file_model_name = "#{ namespace.name }::File"
|
380
|
+
chunk_model_name = "#{ namespace.name }::Chunk"
|
378
381
|
|
379
|
-
|
380
|
-
|
382
|
+
Class.new do
|
383
|
+
include Mongoid::Document
|
381
384
|
|
382
|
-
|
385
|
+
singleton_class = class << self; self; end
|
383
386
|
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
387
|
+
singleton_class.instance_eval do
|
388
|
+
define_method(:name){ chunk_model_name }
|
389
|
+
attr_accessor :file_model
|
390
|
+
attr_accessor :namespace
|
391
|
+
end
|
389
392
|
|
390
|
-
|
393
|
+
self.default_collection_name = "#{ prefix }.chunks"
|
391
394
|
|
392
|
-
|
393
|
-
|
395
|
+
field(:n, :type => Integer, :default => 0)
|
396
|
+
field(:data, :type => (defined?(Moped) ? Moped::BSON::Binary : BSON::Binary))
|
394
397
|
|
395
|
-
|
398
|
+
belongs_to(:file, :foreign_key => :files_id, :class_name => file_model_name)
|
396
399
|
|
397
|
-
|
400
|
+
index({:files_id => 1, :n => -1}, :unique => true)
|
398
401
|
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
+
def namespace
|
403
|
+
self.class.namespace
|
404
|
+
end
|
402
405
|
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
+
def to_s
|
407
|
+
data.data
|
408
|
+
end
|
406
409
|
|
407
|
-
|
410
|
+
alias_method 'to_str', 'to_s'
|
411
|
+
end
|
408
412
|
end
|
409
|
-
end
|
410
413
|
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
414
|
+
##
|
415
|
+
#
|
416
|
+
def GridFS.reading(arg, &block)
|
417
|
+
if arg.respond_to?(:read)
|
418
|
+
rewind(arg) do |io|
|
419
|
+
block.call(io)
|
420
|
+
end
|
421
|
+
else
|
422
|
+
open(arg.to_s) do |io|
|
423
|
+
block.call(io)
|
424
|
+
end
|
421
425
|
end
|
422
426
|
end
|
423
|
-
end
|
424
427
|
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
428
|
+
def GridFS.chunking(io, chunk_size, &block)
|
429
|
+
if io.method(:read).arity == 0
|
430
|
+
data = io.read
|
431
|
+
i = 0
|
432
|
+
loop do
|
433
|
+
offset = i * chunk_size
|
434
|
+
length = i + chunk_size < data.size ? chunk_size : data.size - offset
|
432
435
|
|
433
|
-
|
436
|
+
break if offset >= data.size
|
434
437
|
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
438
|
+
buf = data[offset, length]
|
439
|
+
block.call(buf)
|
440
|
+
i += 1
|
441
|
+
end
|
442
|
+
else
|
443
|
+
while((buf = io.read(chunk_size)))
|
444
|
+
block.call(buf)
|
445
|
+
end
|
442
446
|
end
|
443
447
|
end
|
444
|
-
end
|
445
|
-
|
446
|
-
def GridFS.rewind(io, &block)
|
447
|
-
begin
|
448
|
-
pos = io.pos
|
449
|
-
io.flush
|
450
|
-
io.rewind
|
451
|
-
rescue
|
452
|
-
nil
|
453
|
-
end
|
454
448
|
|
455
|
-
|
456
|
-
block.call(io)
|
457
|
-
ensure
|
449
|
+
def GridFS.rewind(io, &block)
|
458
450
|
begin
|
459
|
-
|
451
|
+
pos = io.pos
|
452
|
+
io.flush
|
453
|
+
io.rewind
|
460
454
|
rescue
|
461
455
|
nil
|
462
456
|
end
|
457
|
+
|
458
|
+
begin
|
459
|
+
block.call(io)
|
460
|
+
ensure
|
461
|
+
begin
|
462
|
+
io.pos = pos
|
463
|
+
rescue
|
464
|
+
nil
|
465
|
+
end
|
466
|
+
end
|
463
467
|
end
|
464
|
-
end
|
465
468
|
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
469
|
+
def GridFS.extract_basename(object)
|
470
|
+
filename = nil
|
471
|
+
[:original_path, :original_filename, :path, :filename, :pathname].each do |msg|
|
472
|
+
if object.respond_to?(msg)
|
473
|
+
filename = object.send(msg)
|
474
|
+
break
|
475
|
+
end
|
472
476
|
end
|
477
|
+
filename ? cleanname(filename) : nil
|
473
478
|
end
|
474
|
-
filename ? cleanname(filename) : nil
|
475
|
-
end
|
476
479
|
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
480
|
+
def GridFS.extract_content_type(filename)
|
481
|
+
content_type = MIME::Types.type_for(::File.basename(filename.to_s)).first
|
482
|
+
content_type.to_s if content_type
|
483
|
+
end
|
481
484
|
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
+
def GridFS.cleanname(pathname)
|
486
|
+
basename = ::File.basename(pathname.to_s)
|
487
|
+
CGI.unescape(basename).gsub(%r/[^0-9a-zA-Z_@)(~.-]/, '_').gsub(%r/_+/,'_')
|
488
|
+
end
|
485
489
|
end
|
486
|
-
end
|
487
490
|
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
GridFS.init!
|
491
|
+
GridFs = GridFS
|
492
|
+
GridFS.init!
|
493
|
+
end
|
data/mongoid-grid_fs.gemspec
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
|
4
4
|
Gem::Specification::new do |spec|
|
5
5
|
spec.name = "mongoid-grid_fs"
|
6
|
-
spec.version = "1.
|
6
|
+
spec.version = "1.3.0"
|
7
7
|
spec.platform = Gem::Platform::RUBY
|
8
8
|
spec.summary = "mongoid-grid_fs"
|
9
9
|
spec.description = "a mongoid 3/moped compatible implementation of the grid_fs specification"
|
@@ -26,9 +26,9 @@ Gem::Specification::new do |spec|
|
|
26
26
|
spec.test_files = nil
|
27
27
|
|
28
28
|
|
29
|
-
spec.add_dependency(*["mongoid", "
|
29
|
+
spec.add_dependency(*["mongoid", "~> 3.0.1"])
|
30
30
|
|
31
|
-
spec.add_dependency(*["mime-types", "
|
31
|
+
spec.add_dependency(*["mime-types", "~> 1.19"])
|
32
32
|
|
33
33
|
|
34
34
|
spec.extensions.push(*[])
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mongoid-grid_fs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,14 +9,14 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-07-
|
12
|
+
date: 2012-07-25 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: mongoid
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
|
-
- -
|
19
|
+
- - ~>
|
20
20
|
- !ruby/object:Gem::Version
|
21
21
|
version: 3.0.1
|
22
22
|
type: :runtime
|
@@ -24,7 +24,7 @@ dependencies:
|
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
25
|
none: false
|
26
26
|
requirements:
|
27
|
-
- -
|
27
|
+
- - ~>
|
28
28
|
- !ruby/object:Gem::Version
|
29
29
|
version: 3.0.1
|
30
30
|
- !ruby/object:Gem::Dependency
|
@@ -32,7 +32,7 @@ dependencies:
|
|
32
32
|
requirement: !ruby/object:Gem::Requirement
|
33
33
|
none: false
|
34
34
|
requirements:
|
35
|
-
- -
|
35
|
+
- - ~>
|
36
36
|
- !ruby/object:Gem::Version
|
37
37
|
version: '1.19'
|
38
38
|
type: :runtime
|
@@ -40,7 +40,7 @@ dependencies:
|
|
40
40
|
version_requirements: !ruby/object:Gem::Requirement
|
41
41
|
none: false
|
42
42
|
requirements:
|
43
|
-
- -
|
43
|
+
- - ~>
|
44
44
|
- !ruby/object:Gem::Version
|
45
45
|
version: '1.19'
|
46
46
|
description: a mongoid 3/moped compatible implementation of the grid_fs specification
|