From 65f32c6f3e93eef3cc78f59d544b4d9764b77110 Mon Sep 17 00:00:00 2001 From: samus Date: Sat, 9 Jan 2010 17:45:18 -0500 Subject: [PATCH] Rearranging some classes and laying out the public api. --- .gitignore | 2 + MongoDB.Driver.GridFS.Tests/GridFSTest.cs | 6 +- MongoDB.Driver.GridFS/GridFS.cs | 127 ------- MongoDB.Driver.GridFS/GridFile.cs | 318 ++++++------------ MongoDB.Driver.GridFS/GridFileInfo.cs | 248 ++++++++++++++ MongoDB.Driver.GridFS/GridFileStream.cs | 66 ++++ .../MongoDB.Driver.GridFS.csproj | 5 +- 7 files changed, 420 insertions(+), 352 deletions(-) delete mode 100644 MongoDB.Driver.GridFS/GridFS.cs create mode 100644 MongoDB.Driver.GridFS/GridFileInfo.cs create mode 100644 MongoDB.Driver.GridFS/GridFileStream.cs diff --git a/.gitignore b/.gitignore index a6b26f3e..28323898 100644 --- a/.gitignore +++ b/.gitignore @@ -29,3 +29,5 @@ MongoDB.Linq.Tests/test-results/* MongoDB.Driver.Benchmark/bin/* MongoDB.Driver.Benchmark/ProfilingSessions/* MongoDB.Driver.Benchmark/obj/* + +/MongoDB.Driver.GridFS.Tests/bin/Debug/nunit.framework.xml \ No newline at end of file diff --git a/MongoDB.Driver.GridFS.Tests/GridFSTest.cs b/MongoDB.Driver.GridFS.Tests/GridFSTest.cs index f3ea9853..76304688 100644 --- a/MongoDB.Driver.GridFS.Tests/GridFSTest.cs +++ b/MongoDB.Driver.GridFS.Tests/GridFSTest.cs @@ -14,8 +14,8 @@ public class GridFSTest{ [Test] public void TestOpenNewGridFile() { - GridFS gridFS = new GridFS(db["tests"]); - using (GridFile gf = new GridFile(gridFS)) + GridFile gridFS = new GridFile(db["tests"]); + using (GridFileInfo gf = new GridFileInfo(gridFS)) { gf.Open("newfile.txt"); Console.WriteLine(gf.Id.ToString()); @@ -24,7 +24,7 @@ public void TestOpenNewGridFile() [Test] public void TestFileDoesNotExist(){ - GridFS fs = new GridFS(db["tests"]); + GridFile fs = new GridFile(db["tests"]); Assert.IsFalse(fs.Exists("non-existent filename")); } diff --git a/MongoDB.Driver.GridFS/GridFS.cs b/MongoDB.Driver.GridFS/GridFS.cs deleted file mode 100644 index 123f0412..00000000 --- a/MongoDB.Driver.GridFS/GridFS.cs +++ /dev/null @@ -1,127 +0,0 @@ -using System; -using System.Text; -using System.IO; -using System.Collections.Generic; - -namespace MongoDB.Driver.GridFS -{ - public class GridFS{ - - private Database db; - - private string name; - - public string Name { - get { return name; } - } - - private IMongoCollection files; - public IMongoCollection Files{ - get { return this.files; } - } - - private IMongoCollection chunks; - public IMongoCollection Chunks{ - get { return this.chunks; } - } - - public GridFS(Database db){ - this.db = db; - this.files = db["fs.files"]; - this.chunks = db["fs.chunks"]; - this.name = "fs"; - } - - public GridFS(Database db, string bucket){ - this.db = db; - this.files = db[bucket + ".files"]; - this.chunks = db[bucket + ".chunks"]; - this.name = "fs"; - } - - public ICursor ListFiles(){ - return this.ListFiles(new Document()); - } - - public ICursor ListFiles(Document query){ - return this.files.Find(new Document().Append("query",query).Append("orderby", new Document().Append("filename", 1))); - } - - public Document Copy(String src, String dest){ - throw new NotImplementedException("Copy"); - } - - public Document Create(String name){ - throw new NotImplementedException("Create"); - } - - #region Delete - public void Delete(Oid id ){ - files.Delete(new Document().Append("_id",id)); - chunks.Delete(new Document().Append("files_id",id)); - } - - public void Delete( String filename ){ - files.Delete(new Document().Append("filename",filename)); - } - - public void Delete(Document query ){ - foreach(Document doc in ListFiles(query).Documents){ - Delete((Oid)doc["_id"]); - } - } - #endregion - - #region Exists - public Boolean Exists(string name){ - return this.files.FindOne(new Document().Append("filename",name)) != null; - } - - public Boolean Exists(Oid id){ - return this.files.FindOne(new Document().Append("_id",id)) != null; - } - - #endregion - - - //public void StoreFile(string filepath) - //{ - // if (File.Exists(filepath)) - // { - // fileStream = new FileStream(filepath, FileMode.Open); - // binaryReader = new BinaryReader(fileStream); - // int chunkNumber = 0; - // int offset = 0; - // int lastSize = (int)fileStream.Length % this.gridFile.ChunkSize; - // double nthChunk = 0; - // if (fileStream.Length > gridFile.ChunkSize) - // { - // nthChunk = Math.Ceiling(fileStream.Length / (double)gridFile.ChunkSize); - // } - // while (offset < fileStream.Length) - // { - // byte[] data = new byte[gridFile.ChunkSize]; - // if (chunkNumber < nthChunk) - // { - // data = binaryReader.ReadBytes(gridFile.ChunkSize); - // } - // else - // { - // data = binaryReader.ReadBytes(lastSize); - // } - - // gridFile.Chunks.Add(new GridChunk(gridFile.Id, chunkNumber, data)); - // offset += gridFile.ChunkSize; - // chunkNumber++; - // } - // } - // else - // { - // throw new IOException("This file does not exist."); - // } - //} - - - } - -} diff --git a/MongoDB.Driver.GridFS/GridFile.cs b/MongoDB.Driver.GridFS/GridFile.cs index 824f99b2..1cc0a50f 100644 --- a/MongoDB.Driver.GridFS/GridFile.cs +++ b/MongoDB.Driver.GridFS/GridFile.cs @@ -1,249 +1,127 @@ using System; -using System.Collections.Generic; -using System.IO; using System.Text; +using System.IO; +using System.Collections.Generic; namespace MongoDB.Driver.GridFS { - public sealed class GridFile : IDisposable - { - private const int DEFAULT_CHUNKSIZE = 256 * 1024; - private const string DEFAULT_CONTENT_TYPE = "text/plain"; - private FileMode fileMode; - private BinaryReader binaryReader; - private FileStream fileStream; - private GridFS gridFS; - private byte[] buffer; - private bool disposed = false; - private bool isOpen = false; + public class GridFile{ + private Database db; - - public GridFile(GridFS gridFS){ - this.gridFS = gridFS; + private string name; + + public string Name { + get { return name; } } - - #region Dispose - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); + private IMongoCollection files; + public IMongoCollection Files{ + get { return this.files; } } - private void Dispose(bool disposing) - { - if (!this.disposed) - { - if (disposing) - { - //TODO - //Dispose managed resources - if (fileStream != null){ - fileStream.Dispose(); - } - if (binaryReader != null){ - binaryReader.Close(); - } - } - } - disposed = true; - isOpen = false; + private IMongoCollection chunks; + public IMongoCollection Chunks{ + get { return this.chunks; } + } + + public GridFile(Database db){ + this.db = db; + this.files = db["fs.files"]; + this.chunks = db["fs.chunks"]; + this.name = "fs"; } - #endregion - public void Open(string filename) - { - Document file = this.gridFS.Files.FindOne(new Document().Append("filename", filename)); - if (file != null) - { - this.id = (Object)file["_id"]; - this.filename = (String)file["filename"]; - this.chunkSize = (Int32)file["chunkSize"]; - this.contentType = (String)file["contentType"]; - this.length = (Int32)file["length"]; - this.aliases = file.Contains("aliases") ? (string[])file["aliases"] : null; - this.uploadDate = (DateTime)file["uploadDate"]; - this.md5 = (string)file["md5"]; - } - else - { - OidGenerator oidGenerator = new OidGenerator(); - this.id = oidGenerator.Generate(); - this.filename = filename; - this.chunkSize = DEFAULT_CHUNKSIZE; - this.contentType = DEFAULT_CONTENT_TYPE; - this.uploadDate = null; - } - this.isOpen = true; + public GridFile(Database db, string bucket){ + this.db = db; + this.files = db[bucket + ".files"]; + this.chunks = db[bucket + ".chunks"]; + this.name = "fs"; } - public void Write(byte[] data) - { - AssertOpen(); - + public ICursor ListFiles(){ + return this.ListFiles(new Document()); } - - public void Read(int length) - { - AssertOpen(); - } - - public void Flush() - { - AssertOpen(); - + + public ICursor ListFiles(Document query){ + return this.files.Find(new Document().Append("query",query).Append("orderby", new Document().Append("filename", 1))); } - - public void Close(){ - AssertOpen(); - Dispose(); + + public Document Copy(String src, String dest){ + throw new NotImplementedException("Copy"); } - - public bool FileExists(string filename) - { - ICursor results = this.gridFS.Files.Find(new Document().Append("filename", filename)); - if (results != null) - { - return true; - } - else return false; + + public Document Create(String name){ + throw new NotImplementedException("Create"); } - - public List List(string collectionName) - { - List names = new List(); - ICursor cursor = this.gridFS.Files.FindAll(); - if (cursor == null) - { - //TODO: Make MongoExcption - throw new Exception(); - } - else - foreach (Document file in cursor.Documents) - { - names.Add((string)file["filename"]); - } - return names; + + #region Delete + public void Delete(Oid id ){ + files.Delete(new Document().Append("_id",id)); + chunks.Delete(new Document().Append("files_id",id)); } - - private void AssertOpen() - { - if (!isOpen){ - throw new MongoGridFSException("Cannot write to a file when it is closed.", this.filename, new Exception("file is closed")); - } + + public void Delete( String filename ){ + files.Delete(new Document().Append("filename",filename)); } - - private void FlushWriteBuffer() - { - List chunks = new List(); - int chunkNumber = 0; - int offset = 0; - int lastSize = (int)fileStream.Length % this.chunkSize; - double nthChunk = 0; - if (buffer.Length > this.chunkSize) - { - nthChunk = Math.Floor(buffer.Length / (double)this.chunkSize); - while (offset < fileStream.Length) - { - byte[] data = new byte[this.chunkSize]; - if (chunkNumber < nthChunk) - { - data = binaryReader.ReadBytes(this.chunkSize); - Array.Copy(buffer, offset, data, 0, chunkSize); - } - else - { - Array.Copy(buffer, offset, data, 0, lastSize); - } - GridChunk gridChunk = new GridChunk(this.id, chunkNumber, data); - chunks.Add(gridChunk.ToDocument()); - offset += this.chunkSize; - chunkNumber++; - } - } - else { - GridChunk gridChunk = new GridChunk(id, 0, buffer); - chunks.Add(gridChunk.ToDocument()); + + public void Delete(Document query ){ + foreach(Document doc in ListFiles(query).Documents){ + Delete((Oid)doc["_id"]); } - - this.gridFS.Chunks.Insert(chunks); - - - } - - - - - private Object id; - public Object Id{ - get { return this.id; } - set { this.id = value; } - } - - private string filename; - public string Filename - { - get { return this.filename; } - set { this.filename = value; } - } - - private string contentType; - public string ContentType{ - get { return this.contentType; } - set { this.contentType = value; } - } - - private int length; - public int Length{ - get { return this.length; } - set { this.length = value; } - } - - private string[] aliases; - public string[] Aliases{ - get { return this.aliases; } - set { this.aliases = value; } } - - private int chunkSize; - public int ChunkSize{ - get { return this.chunkSize; } - set { this.chunkSize = value; } - } - - private Object metadata; - public Object Metadata{ - get { return this.metadata; } + #endregion + + #region Exists + public Boolean Exists(string name){ + return this.files.FindOne(new Document().Append("filename",name)) != null; } - private DateTime? uploadDate; - public DateTime? UploadDate{ - get { return this.uploadDate; } - set { this.uploadDate = value; } + public Boolean Exists(Oid id){ + return this.files.FindOne(new Document().Append("_id",id)) != null; } - private string md5; - public string Md5{ - get { return this.md5; } - set { this.md5 = value; } - } - - public Document ToDocument(){ - Document doc = new Document(); - doc["_id"] = this.id; - doc["filename"] = this.filename; - doc["contentType"] = this.contentType; - doc["length"] = this.length; - doc["chunkSize"] = this.chunkSize; - if (this.uploadDate != null){ - doc["uploadDate"] = this.uploadDate; - } - return doc; - } - - - - + #endregion + + + //public void StoreFile(string filepath) + //{ + // if (File.Exists(filepath)) + // { + // fileStream = new FileStream(filepath, FileMode.Open); + // binaryReader = new BinaryReader(fileStream); + // int chunkNumber = 0; + // int offset = 0; + // int lastSize = (int)fileStream.Length % this.gridFile.ChunkSize; + // double nthChunk = 0; + // if (fileStream.Length > gridFile.ChunkSize) + // { + // nthChunk = Math.Ceiling(fileStream.Length / (double)gridFile.ChunkSize); + // } + // while (offset < fileStream.Length) + // { + // byte[] data = new byte[gridFile.ChunkSize]; + // if (chunkNumber < nthChunk) + // { + // data = binaryReader.ReadBytes(gridFile.ChunkSize); + // } + // else + // { + // data = binaryReader.ReadBytes(lastSize); + // } + + // gridFile.Chunks.Add(new GridChunk(gridFile.Id, chunkNumber, data)); + // offset += gridFile.ChunkSize; + // chunkNumber++; + // } + // } + // else + // { + // throw new IOException("This file does not exist."); + // } + //} + + } + } diff --git a/MongoDB.Driver.GridFS/GridFileInfo.cs b/MongoDB.Driver.GridFS/GridFileInfo.cs new file mode 100644 index 00000000..ecb2f79f --- /dev/null +++ b/MongoDB.Driver.GridFS/GridFileInfo.cs @@ -0,0 +1,248 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; + +namespace MongoDB.Driver.GridFS +{ + /// + /// Provides instance methods for the creation, copying, deletion, moving, and opening of files, + /// and aids in the creation of GridFileStream objects. It also contains + /// + public sealed class GridFileInfo + { + private const int DEFAULT_CHUNKSIZE = 256 * 1024; + private const string DEFAULT_CONTENT_TYPE = "text/plain"; + private FileMode fileMode; + private BinaryReader binaryReader; + private FileStream fileStream; + private GridFile gridFile; + private byte[] buffer; + private bool disposed = false; + private bool isOpen = false; + + + private Object id; + public Object Id{ + get { return this.id; } + set { this.id = value; } + } + + private string filename; + public string Filename + { + get { return this.filename; } + set { this.filename = value; } + } + + private string contentType; + public string ContentType{ + get { return this.contentType; } + set { this.contentType = value; } + } + + private int length; + public int Length{ + get { return this.length; } + set { this.length = value; } + } + + private string[] aliases; + public string[] Aliases{ + get { return this.aliases; } + set { this.aliases = value; } + } + + private int chunkSize; + public int ChunkSize{ + get { return this.chunkSize; } + set { this.chunkSize = value; } + } + + private Object metadata; + public Object Metadata{ + get { return this.metadata; } + } + + private DateTime? uploadDate; + public DateTime? UploadDate{ + get { return this.uploadDate; } + set { this.uploadDate = value; } + } + private string md5; + public string Md5{ + get { return this.md5; } + set { this.md5 = value; } + } + + public GridFileInfo(GridFile gridFile){ + this.gridFile = gridFile; + } + + + #region Dispose + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + private void Dispose(bool disposing) + { + if (!this.disposed) + { + if (disposing) + { + //TODO + //Dispose managed resources + if (fileStream != null){ + fileStream.Dispose(); + } + if (binaryReader != null){ + binaryReader.Close(); + } + } + } + disposed = true; + isOpen = false; + } + #endregion + + public void Open(string filename) + { + Document file = this.gridFile.Files.FindOne(new Document().Append("filename", filename)); + if (file != null) + { + this.id = (Object)file["_id"]; + this.filename = (String)file["filename"]; + this.chunkSize = (Int32)file["chunkSize"]; + this.contentType = (String)file["contentType"]; + this.length = (Int32)file["length"]; + this.aliases = file.Contains("aliases") ? (string[])file["aliases"] : null; + this.uploadDate = (DateTime)file["uploadDate"]; + this.md5 = (string)file["md5"]; + } + else + { + OidGenerator oidGenerator = new OidGenerator(); + this.id = oidGenerator.Generate(); + this.filename = filename; + this.chunkSize = DEFAULT_CHUNKSIZE; + this.contentType = DEFAULT_CONTENT_TYPE; + this.uploadDate = null; + } + this.isOpen = true; + } + + public void Write(byte[] data) + { + AssertOpen(); + + } + + public void Read(int length) + { + AssertOpen(); + } + + public void Flush() + { + AssertOpen(); + + } + + public void Close(){ + AssertOpen(); + Dispose(); + } + + public bool FileExists(string filename) + { + ICursor results = this.gridFile.Files.Find(new Document().Append("filename", filename)); + if (results != null) + { + return true; + } + else return false; + } + + public List List(string collectionName) + { + List names = new List(); + ICursor cursor = this.gridFile.Files.FindAll(); + if (cursor == null) + { + //TODO: Make MongoExcption + throw new Exception(); + } + else + foreach (Document file in cursor.Documents) + { + names.Add((string)file["filename"]); + } + return names; + } + + private void AssertOpen() + { + if (!isOpen){ + throw new MongoGridFSException("Cannot write to a file when it is closed.", this.filename, new Exception("file is closed")); + } + } + + private void FlushWriteBuffer() + { + List chunks = new List(); + int chunkNumber = 0; + int offset = 0; + int lastSize = (int)fileStream.Length % this.chunkSize; + double nthChunk = 0; + if (buffer.Length > this.chunkSize) + { + nthChunk = Math.Floor(buffer.Length / (double)this.chunkSize); + while (offset < fileStream.Length) + { + byte[] data = new byte[this.chunkSize]; + if (chunkNumber < nthChunk) + { + data = binaryReader.ReadBytes(this.chunkSize); + Array.Copy(buffer, offset, data, 0, chunkSize); + } + else + { + Array.Copy(buffer, offset, data, 0, lastSize); + } + GridChunk gridChunk = new GridChunk(this.id, chunkNumber, data); + chunks.Add(gridChunk.ToDocument()); + offset += this.chunkSize; + chunkNumber++; + } + } + else { + GridChunk gridChunk = new GridChunk(id, 0, buffer); + chunks.Add(gridChunk.ToDocument()); + } + + this.gridFile.Chunks.Insert(chunks); + + + } + + public Document ToDocument(){ + Document doc = new Document(); + doc["_id"] = this.id; + doc["filename"] = this.filename; + doc["contentType"] = this.contentType; + doc["length"] = this.length; + doc["chunkSize"] = this.chunkSize; + if (this.uploadDate != null){ + doc["uploadDate"] = this.uploadDate; + } + return doc; + } + + + + + } +} diff --git a/MongoDB.Driver.GridFS/GridFileStream.cs b/MongoDB.Driver.GridFS/GridFileStream.cs new file mode 100644 index 00000000..cc92e305 --- /dev/null +++ b/MongoDB.Driver.GridFS/GridFileStream.cs @@ -0,0 +1,66 @@ + +using System; +using System.IO; + +namespace MongoDB.Driver.GridFS +{ + /// + /// Stream for reading and writing to a file in GridFS. + /// + public class GridFileStream : Stream + { + private GridFileInfo gridFileInfo; + + #region Properties + public override bool CanRead { + get { return true; } + } + public override bool CanWrite { + get { return true; } + } + public override bool CanSeek { + get { return true; } + } + + public override long Length { + get { + return gridFileInfo.Length; + } + } + + private long position; + public override long Position { + get { + return position; + } + set { + position = value; + } + } + #endregion + + public GridFileStream(GridFileInfo gridfileinfo){ + this.gridFileInfo = gridFileInfo; + } + + public override void Write(byte[] buffer, int offset, int count){ + throw new NotImplementedException(); + } + + public override long Seek(long offset, SeekOrigin origin){ + throw new NotImplementedException(); + } + + public override void SetLength(long value){ + throw new NotImplementedException(); + } + + public override void Flush(){ + throw new NotImplementedException(); + } + + public override int Read(byte[] buffer, int offset, int count){ + throw new NotImplementedException(); + } + } +} diff --git a/MongoDB.Driver.GridFS/MongoDB.Driver.GridFS.csproj b/MongoDB.Driver.GridFS/MongoDB.Driver.GridFS.csproj index bfaeefb3..549f6fdd 100644 --- a/MongoDB.Driver.GridFS/MongoDB.Driver.GridFS.csproj +++ b/MongoDB.Driver.GridFS/MongoDB.Driver.GridFS.csproj @@ -46,9 +46,10 @@ - + - + +