Class: RCS::Common::GridFS::Bucket

Inherits:
Object
  • Object
show all
Defined in:
lib/rcs-common/gridfs.rb

Constant Summary collapse

DEFAULT_NAME =
'fs'
DEFAULT_CONTENT_TYPE =
'application/octet-stream'
DEFAULT_CHUNK_SIZE =
262144
BINARY_ENCODING =
'BINARY'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name = DEFAULT_NAME, options = {}) ⇒ Bucket

Returns a new instance of Bucket.



97
98
99
100
101
102
103
104
105
# File 'lib/rcs-common/gridfs.rb', line 97

def initialize(name = DEFAULT_NAME, options = {})
  @name                 = name.to_s.downcase.strip
  @name                 = DEFAULT_NAME if @name.empty?
  @mongoid_session_name = options[:mongoid_session_name] || :default
  @setup_on_write       = options[:lazy].nil? ? true : options[:lazy]
  @osx                  = RbConfig::CONFIG['host_os'] =~ /darwin/

  setup unless @setup_on_write
end

Instance Attribute Details

#mongoid_session_nameObject (readonly)

Returns the value of attribute mongoid_session_name.



90
91
92
# File 'lib/rcs-common/gridfs.rb', line 90

def mongoid_session_name
  @mongoid_session_name
end

#nameObject (readonly)

Returns the value of attribute name.



90
91
92
# File 'lib/rcs-common/gridfs.rb', line 90

def name
  @name
end

Instance Method Details

#append(file_id, data, options = {}) ⇒ Object



157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'lib/rcs-common/gridfs.rb', line 157

def append(file_id, data, options = {})
  attributes = if options[:filename]
    files_collection.find(filename: file_id).first
  else
    file_id = objectid(file_id)
    files_collection.find(_id: file_id).first
  end

  if !attributes and options[:create]
    file_attributes = options[:create].respond_to?(:[]) ? options[:create] : {}
    new_file_id = put(data, file_attributes, options)
    return [new_file_id, data.bytesize]
  end

  raise("File not found: #{file_id}") unless attributes

  attributes = attributes.to_h.symbolize_keys

  file_id = objectid(attributes[:_id])

  length, chunk_size = attributes[:length], attributes[:chunkSize]

  chunk_offset = (length / chunk_size).to_i
  offset = length % chunk_size

  if offset > 0
    data = chunks_collection.find(files_id: file_id, n: chunk_offset).first['data'].data + data
  end

  chunkerize(data) do |chunk_data, chunk_num|
    chunks_collection.find(files_id: file_id, n: chunk_num + chunk_offset).upsert('$set' => {data: binary(chunk_data)})
  end

  new_md5 = md5(file_id) if options[:md5] != false
  new_length = length - offset + data.bytesize

  files_collection.find(_id: file_id).update('$set' => {length: new_length, md5: new_md5})

  [file_id, new_length]
end

#chunks_collectionObject



122
123
124
# File 'lib/rcs-common/gridfs.rb', line 122

def chunks_collection
  session[:"#{name}.chunks"]
end

#content(file_id) ⇒ Object

Equivalent to #get(id).read



199
200
201
202
203
204
205
# File 'lib/rcs-common/gridfs.rb', line 199

def content(file_id)
  file_id = objectid(file_id)

  chunks_collection.find(files_id: file_id, n: {'$gte' => 0}).inject("") do |data, chunk|
    data << chunk['data'].data
  end
end

#delete(file_id) ⇒ Object Also known as: remove



222
223
224
225
226
227
228
229
# File 'lib/rcs-common/gridfs.rb', line 222

def delete(file_id)
  file_id = objectid(file_id)

  files_collection.find(_id: file_id).remove
  chunks_collection.find(files_id: file_id).remove_all

  return nil
end

#dropObject



231
232
233
234
# File 'lib/rcs-common/gridfs.rb', line 231

def drop
  [files_collection, chunks_collection].map(&:drop)
  @setup_on_write = true
end

#files_collectionObject



118
119
120
# File 'lib/rcs-common/gridfs.rb', line 118

def files_collection
  session[:"#{name}.files"]
end

#get(file_id, options = {}) ⇒ Object



207
208
209
210
211
212
213
214
215
216
217
218
219
220
# File 'lib/rcs-common/gridfs.rb', line 207

def get(file_id, options = {})
  file_id = objectid(file_id)
  attributes = files_collection.find(_id: file_id).first

  return unless attributes

  attributes = attributes.to_h.symbolize_keys
  attributes[:bucket] = self
  attributes[:chunk_size] = attributes[:chunkSize]
  attributes[:content_type] = attributes[:contentType]
  attributes[:upload_date] = attributes[:uploadDate]

  ReadOnlyFile.new(self, attributes)
end

#md5(file_id) ⇒ Object



152
153
154
155
# File 'lib/rcs-common/gridfs.rb', line 152

def md5(file_id)
  doc = session.command(filemd5: file_id, root: name)
  doc['md5'] if doc.respond_to?(:[])
end

#put(content, attrs = {}, options = {}) ⇒ Object



126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/rcs-common/gridfs.rb', line 126

def put(content, attrs = {}, options = {})
  return if content.nil?

  file = {}

  file[:_id]         = BSON::ObjectId.new
  file[:length]      = content.bytesize
  file[:chunkSize]   = DEFAULT_CHUNK_SIZE

  return if file[:length].zero?

  file[:filename]    = attrs[:filename]
  file[:contentType] = attrs[:content_type] || attrs[:contentType] || DEFAULT_CONTENT_TYPE
  file[:aliases]     = attrs[:aliases] || []
  file[:aliases]     = [file[:aliases]].flatten
  file[:metadata]    = attrs[:metadata] || {}
  file[:metadata]    = {} if file[:metadata].blank?
  file[:uploadDate]  = attrs[:upload_date] || attrs[:uploadDate] || Time.now.utc

  file[:md5] = write(file[:_id], content, options)

  files_collection.insert(file)

  file[:_id]
end

#sessionObject



114
115
116
# File 'lib/rcs-common/gridfs.rb', line 114

def session
  Mongoid.session(mongoid_session_name).with(session_options)
end

#session_optionsObject



107
108
109
110
111
112
# File 'lib/rcs-common/gridfs.rb', line 107

def session_options
  # Allow unsafe write on OSX.
  # @see https://github.com/mongoid/mongoid/issues/3582

  @osx ? {safe: false} : {}
end