# Copyright (C) 2014-2015 MongoDB, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. module Mongo module Grid class File # Encapsulates behaviour around GridFS chunks of file data. # # @since 2.0.0 class Chunk # Name of the chunks collection. # # @since 2.0.0 COLLECTION = 'chunks'.freeze # Default size for chunks of data. # # @since 2.0.0 DEFAULT_SIZE = (255 * 1024).freeze # @return [ BSON::Document ] document The document to store for the # chunk. attr_reader :document # Check chunk equality. # # @example Check chunk equality. # chunk == other # # @param [ Object ] other The object ot compare to. # # @return [ true, false ] If the objects are equal. # # @since 2.0.0 def ==(other) return false unless other.is_a?(Chunk) document == other.document end # Get the BSON type for a chunk document. # # @example Get the BSON type. # chunk.bson_type # # @return [ Integer ] The BSON type. # # @since 2.0.0 def bson_type BSON::Hash::BSON_TYPE end # Get the chunk data. # # @example Get the chunk data. # chunk.data # # @return [ BSON::Binary ] The chunk data. # # @since 2.0.0 def data document[:data] end # Get the chunk id. # # @example Get the chunk id. # chunk.id # # @return [ BSON::ObjectId ] The chunk id. # # @since 2.0.0 def id document[:_id] end # Get the files id. # # @example Get the files id. # chunk.files_id # # @return [ BSON::ObjectId ] The files id. # # @since 2.0.0 def files_id document[:files_id] end # Get the chunk position. # # @example Get the chunk position. # chunk.n # # @return [ Integer ] The chunk position. # # @since 2.0.0 def n document[:n] end # Create the new chunk. # # @example Create the chunk. # Chunk.new(document) # # @param [ BSON::Document ] document The document to create the chunk # from. # # @since 2.0.0 def initialize(document) @document = BSON::Document.new(:_id => BSON::ObjectId.new).merge(document) end # Conver the chunk to BSON for storage. # # @example Convert the chunk to BSON. # chunk.to_bson # # @param [ String ] encoded The encoded data to append to. # # @return [ String ] The raw BSON data. # # @since 2.0.0 def to_bson(encoded = ''.force_encoding(BSON::BINARY)) document.to_bson(encoded) end class << self # Takes an array of chunks and assembles them back into the full # piece of raw data. # # @example Assemble the chunks. # Chunk.assemble(chunks) # # @param [ Array ] chunks The chunks. # # @return [ String ] The assembled data. # # @since 2.0.0 def assemble(chunks) chunks.reduce(''){ |data, chunk| data << chunk.data.data } end # Split the provided data into multiple chunks. # # @example Split the data into chunks. # Chunks.split(data) # # @param [ String ] data The raw bytes. # @param [ Metadata ] metadata The file metadata. # # @return [ Array ] The chunks of the data. # # @since 2.0.0 def split(data, metadata) chunks, index, n = [], 0, 0 while index < data.length bytes = data.slice(index, metadata.chunk_size) metadata.md5.update(bytes) chunk = Chunk.new(:data => BSON::Binary.new(bytes), :files_id => metadata.id, :n => n) chunks.push(chunk) index += bytes.length n += 1 end chunks end end end end end end