/// <summary> /// Refreshes the GridFS file info from the server. /// </summary> public void Refresh() { using (_server.RequestStart(_serverInstance)) { var gridFS = new MongoGridFS(_server, _databaseName, _settings); var database = gridFS.GetDatabase(); var filesCollection = gridFS.GetFilesCollection(database); MongoCursor <BsonDocument> cursor; if (_id != null) { cursor = filesCollection.Find(Query.EQ("_id", _id)); } else if (_name != null) { cursor = filesCollection.Find(Query.EQ("filename", _name)).SetSortOrder(SortBy.Descending("uploadDate")); } else { throw new InvalidOperationException("Cannot refresh FileInfo when both Id and Name are missing."); } var fileInfo = cursor.SetLimit(1).FirstOrDefault(); CacheFileInfo(fileInfo); // fileInfo will be null if file does not exist } }
private void UpdateMetadata() { using (_fileInfo.Server.RequestStart(null, ReadPreference.Primary)) { var gridFS = new MongoGridFS(_fileInfo.Server, _fileInfo.DatabaseName, _fileInfo.GridFSSettings); var database = gridFS.GetDatabase(ReadPreference.Primary); var filesCollection = gridFS.GetFilesCollection(database); BsonValue md5 = BsonNull.Value; if (_updateMD5) { var md5Command = new CommandDocument { { "filemd5", _fileInfo.Id }, { "root", gridFS.Settings.Root } }; var md5Result = database.RunCommand(md5Command); md5 = md5Result.Response["md5"].AsString; } var query = Query.EQ("_id", _fileInfo.Id); var update = Update .Set("length", _length) .Set("md5", md5); filesCollection.Update(query, update); } }
/// <summary> /// Moves the most recent version of a GridFS file. /// </summary> /// <param name="destFileName">The destination file name.</param> public void MoveTo(string destFileName) { EnsureServerInstanceIsPrimary(); using (_server.RequestStart(_serverInstance)) { var gridFS = new MongoGridFS(_server, _databaseName, _settings); var database = gridFS.GetDatabase(ReadPreference.Primary); var filesCollection = gridFS.GetFilesCollection(database); var query = Query.EQ("_id", _id); var update = Update.Set("filename", destFileName); filesCollection.Update(query, update); } }
// private methods private void AddMissingChunks() { using (_fileInfo.Server.RequestStart(null, _fileInfo.ServerInstance)) { var gridFS = new MongoGridFS(_fileInfo.Server, _fileInfo.DatabaseName, _fileInfo.GridFSSettings); var database = gridFS.GetDatabase(ReadPreference.Primary); var chunksCollection = gridFS.GetChunksCollection(database); var query = Query.EQ("files_id", _fileInfo.Id); var fields = Fields.Include("n"); var chunkCount = (_length + _fileInfo.ChunkSize - 1) / _fileInfo.ChunkSize; var chunksFound = new HashSet <long>(); var foundExtraChunks = false; foreach (var chunk in chunksCollection.Find(query).SetFields(fields)) { var n = chunk["n"].ToInt64(); chunksFound.Add(n); if (n >= chunkCount) { foundExtraChunks = true; } } if (foundExtraChunks) { var extraChunksQuery = Query.And(Query.EQ("files_id", _fileInfo.Id), Query.GTE("n", chunkCount)); chunksCollection.Remove(extraChunksQuery); } BsonBinaryData zeros = null; // delay creating it until it's actually needed for (var n = 0L; n < chunkCount; n++) { if (!chunksFound.Contains(n)) { if (zeros == null) { zeros = new BsonBinaryData(new byte[_fileInfo.ChunkSize]); } var missingChunk = new BsonDocument { { "_id", ObjectId.GenerateNewId() }, { "files_id", _fileInfo.Id }, { "n", (n < int.MaxValue) ? (BsonValue) new BsonInt32((int)n) : new BsonInt64(n) }, { "data", zeros } }; chunksCollection.Insert(missingChunk); } } } }
private void LoadChunk(long chunkIndex) { if (_chunkIsDirty) { SaveChunk(); } using (_fileInfo.Server.RequestStart(null, _fileInfo.ServerInstance)) { var gridFS = new MongoGridFS(_fileInfo.Server, _fileInfo.DatabaseName, _fileInfo.GridFSSettings); var database = gridFS.GetDatabase(); var chunksCollection = gridFS.GetChunksCollection(database); var query = Query.And(Query.EQ("files_id", _fileInfo.Id), Query.EQ("n", chunkIndex)); var document = chunksCollection.FindOne(query); if (document == null) { if (_chunk == null) { _chunk = new byte[_fileInfo.ChunkSize]; } else { Array.Clear(_chunk, 0, _chunk.Length); } _chunkId = ObjectId.GenerateNewId(); } else { var bytes = document["data"].AsBsonBinaryData.Bytes; if (bytes.Length == _fileInfo.ChunkSize) { _chunk = bytes; } else { if (_chunk == null) { _chunk = new byte[_fileInfo.ChunkSize]; } Buffer.BlockCopy(bytes, 0, _chunk, 0, bytes.Length); Array.Clear(_chunk, bytes.Length, _chunk.Length - bytes.Length); } _chunkId = document["_id"]; } _chunkIndex = chunkIndex; } }
private void SaveChunk() { using (_fileInfo.Server.RequestStart(_fileInfo.ServerInstance)) { var connectionId = _fileInfo.Server.RequestConnectionId; var gridFS = new MongoGridFS(_fileInfo.Server, _fileInfo.DatabaseName, _fileInfo.GridFSSettings); var database = gridFS.GetDatabase(ReadPreference.Primary); var chunksCollection = gridFS.GetChunksCollection(database); var lastChunkIndex = (_length + _fileInfo.ChunkSize - 1) / _fileInfo.ChunkSize - 1; if (_chunkIndex == -1 || _chunkIndex > lastChunkIndex) { var message = string.Format("Invalid chunk index {0}.", _chunkIndex); throw new MongoGridFSException(connectionId, message); } var lastChunkSize = (int)(_length % _fileInfo.ChunkSize); if (lastChunkSize == 0) { lastChunkSize = _fileInfo.ChunkSize; } BsonBinaryData data; if (_chunkIndex < lastChunkIndex || lastChunkSize == _fileInfo.ChunkSize) { data = new BsonBinaryData(_chunk); } else { var lastChunk = new byte[lastChunkSize]; Buffer.BlockCopy(_chunk, 0, lastChunk, 0, lastChunkSize); data = new BsonBinaryData(lastChunk); } var query = Query.EQ("_id", _chunkId); var update = new UpdateDocument { { "_id", _chunkId }, { "files_id", _fileInfo.Id }, { "n", _chunkIndex < int.MaxValue ? (BsonValue)(BsonInt32)(int)_chunkIndex : (BsonInt64)_chunkIndex }, { "data", data } }; chunksCollection.Update(query, update, UpdateFlags.Upsert); _chunkIsDirty = false; } }
/// <summary> /// Deletes a GridFS file. /// </summary> public void Delete() { EnsureServerInstanceIsPrimary(); using (_server.RequestStart(_serverInstance)) { var gridFS = new MongoGridFS(_server, _databaseName, _settings); gridFS.EnsureIndexes(); if (Exists) { var database = gridFS.GetDatabase(ReadPreference.Primary); var filesCollection = gridFS.GetFilesCollection(database); var chunksCollection = gridFS.GetChunksCollection(database); filesCollection.Remove(Query.EQ("_id", _id), gridFS.Settings.WriteConcern); chunksCollection.Remove(Query.EQ("files_id", _id), gridFS.Settings.WriteConcern); } } }
private void OpenCreate() { EnsureServerInstanceIsPrimary(); using (_fileInfo.Server.RequestStart(null, _fileInfo.ServerInstance)) { var gridFS = new MongoGridFS(_fileInfo.Server, _fileInfo.DatabaseName, _fileInfo.GridFSSettings); var database = gridFS.GetDatabase(ReadPreference.Primary); var filesCollection = gridFS.GetFilesCollection(database); gridFS.EnsureIndexes(); _fileIsDirty = true; if (_fileInfo.Id == null) { _fileInfo.SetId(ObjectId.GenerateNewId()); } var aliases = (_fileInfo.Aliases != null) ? new BsonArray(_fileInfo.Aliases) : null; var file = new BsonDocument { { "_id", _fileInfo.Id }, { "filename", _fileInfo.Name, !string.IsNullOrEmpty(_fileInfo.Name) }, { "length", 0 }, { "chunkSize", _fileInfo.ChunkSize }, { "uploadDate", _fileInfo.UploadDate }, { "md5", BsonNull.Value }, // will be updated when the file is closed (unless UpdateMD5 is false) { "contentType", _fileInfo.ContentType, !string.IsNullOrEmpty(_fileInfo.ContentType) }, // optional { "aliases", aliases, aliases != null }, // optional { "metadata", _fileInfo.Metadata, _fileInfo.Metadata != null } // optional }; filesCollection.Insert(file); _length = 0; _position = 0; } }
private void LoadChunkNoData(long chunkIndex) { if (_chunkIsDirty) { SaveChunk(); } using (_fileInfo.Server.RequestStart(null, _fileInfo.ServerInstance)) { var gridFS = new MongoGridFS(_fileInfo.Server, _fileInfo.DatabaseName, _fileInfo.GridFSSettings); var database = gridFS.GetDatabase(); var chunksCollection = gridFS.GetChunksCollection(database); if (_chunk == null) { _chunk = new byte[_fileInfo.ChunkSize]; } else { Array.Clear(_chunk, 0, _chunk.Length); } var query = Query.And(Query.EQ("files_id", _fileInfo.Id), Query.EQ("n", chunkIndex)); var fields = Fields.Include("_id"); var document = chunksCollection.Find(query).SetFields(fields).SetLimit(1).FirstOrDefault(); if (document == null) { _chunkId = ObjectId.GenerateNewId(); } else { _chunkId = document["_id"]; } _chunkIndex = chunkIndex; } }
private void SaveChunk() { using (_fileInfo.Server.RequestStart(null, _fileInfo.ServerInstance)) { var gridFS = new MongoGridFS(_fileInfo.Server, _fileInfo.DatabaseName, _fileInfo.GridFSSettings); var database = gridFS.GetDatabase(ReadPreference.Primary); var chunksCollection = gridFS.GetChunksCollection(database); var lastChunkIndex = (_length + _fileInfo.ChunkSize - 1) / _fileInfo.ChunkSize - 1; if (_chunkIndex == -1 || _chunkIndex > lastChunkIndex) { var message = string.Format("Invalid chunk index {0}.", _chunkIndex); throw new MongoGridFSException(message); } var lastChunkSize = (int)(_length % _fileInfo.ChunkSize); if (lastChunkSize == 0) { lastChunkSize = _fileInfo.ChunkSize; } BsonBinaryData data; if (_chunkIndex < lastChunkIndex || lastChunkSize == _fileInfo.ChunkSize) { data = new BsonBinaryData(_chunk); } else { var lastChunk = new byte[lastChunkSize]; Buffer.BlockCopy(_chunk, 0, lastChunk, 0, lastChunkSize); data = new BsonBinaryData(lastChunk); } var query = Query.EQ("_id", _chunkId); var update = new UpdateDocument { { "_id", _chunkId }, { "files_id", _fileInfo.Id }, { "n", (_chunkIndex < int.MaxValue) ? (BsonValue)new BsonInt32((int)_chunkIndex) : new BsonInt64(_chunkIndex) }, { "data", data } }; chunksCollection.Update(query, update, UpdateFlags.Upsert); _chunkIsDirty = false; } }
// private methods private void AddMissingChunks() { using (_fileInfo.Server.RequestStart(null, _fileInfo.ServerInstance)) { var gridFS = new MongoGridFS(_fileInfo.Server, _fileInfo.DatabaseName, _fileInfo.GridFSSettings); var database = gridFS.GetDatabase(ReadPreference.Primary); var chunksCollection = gridFS.GetChunksCollection(database); var query = Query.EQ("files_id", _fileInfo.Id); var fields = Fields.Include("n"); var chunkCount = (_length + _fileInfo.ChunkSize - 1) / _fileInfo.ChunkSize; var chunksFound = new HashSet<long>(); var foundExtraChunks = false; foreach (var chunk in chunksCollection.Find(query).SetFields(fields)) { var n = chunk["n"].ToInt64(); chunksFound.Add(n); if (n >= chunkCount) { foundExtraChunks = true; } } if (foundExtraChunks) { var extraChunksQuery = Query.And(Query.EQ("files_id", _fileInfo.Id), Query.GTE("n", chunkCount)); chunksCollection.Remove(extraChunksQuery); } BsonBinaryData zeros = null; // delay creating it until it's actually needed for (var n = 0L; n < chunkCount; n++) { if (!chunksFound.Contains(n)) { if (zeros == null) { zeros = new BsonBinaryData(new byte[_fileInfo.ChunkSize]); } var missingChunk = new BsonDocument { { "_id", ObjectId.GenerateNewId() }, { "files_id", _fileInfo.Id }, { "n", (n < int.MaxValue) ? (BsonValue)new BsonInt32((int)n) : new BsonInt64(n) }, { "data", zeros } }; chunksCollection.Insert(missingChunk); } } } }