RavenDB - Photo Gallery Project (X)-File Storage

Published on 2010-10-12

The code for this and all other entries can be found here: http://github.com/robashton/RavenGallery/ 

In the last entry we discussed the actual model being used to store information about uploaded images, and left an interface ready to fill out for dealing with the actual persistence of file data.

We can’t store the file data as part of the document (We could, but it would be a really bad place to put it), and we would most likely place the image data on a dedicated server or shift it off to the cloud using whatever is cool at the moment.

Because this is a blog series about RavenDB we’ll use that RavenDB to do it and see how that plays out, so I’ve created an instance of IFileStorageService called RavenFileStorageService for that purpose.

As I’m once again dealing with RavenDB, let’s go and create the test for this in the Integration test assembly created in the last blog entry.

   1:      [TestFixture]
   2:      public class RavenFileStorageServiceTests : LocalRavenTest
   3:      {
   4:          [Test]
   5:          public void WhenStoreFileInvokedWithValidArguments_AttachmentIsCreatedInRaven()
   6:          {
   7:              Byte[] fileBytes = new Byte[] { 3,1,4,1,5,9};
   8:              String filename = "images/mySuperDuperFile";
   9:              RavenFileStorageService storage = new RavenFileStorageService(this.Store);
  10:   
  11:              storage.StoreFile(filename, fileBytes);
  12:   
  13:              var retrievedAttachment = this.Store.DatabaseCommands.GetAttachment(filename);
  14:              Assert.AreEqual(fileBytes, retrievedAttachment.Data);
  15:          }
  16:      }
 
 

We don’t deal with the Unit of Work when uploading attachments, so we talk to the IDocumentStore directly (IE, they are outside the scope of the normal document session transaction). Retrieving an attachment as seen above is just a case of calling GetAttachment with the ‘key’ that it was uploaded with (in this case a path with a folder in it).

Storing the file happens in much the same way, so we inject the IDocumentStore into our RavenFileStorageService and get on with looking at how we do this.

   1:      public class RavenFileStorageService : IFileStorageService
   2:      {
   3:          private IDocumentStore documentStore;
   4:   
   5:          public RavenFileStorageService(IDocumentStore documentStore)
   6:          {
   7:              this.documentStore = documentStore;
   8:          }
   9:          public void StoreFile(string filename, byte[] bytes)
  10:          {
  11:              documentStore.DatabaseCommands.PutAttachment(filename, null, bytes, new Newtonsoft.Json.Linq.JObject());
  12:          }
  13:      }

There, a simple call to PutAttachment is all it takes. We ignore the e-tag argument because we not performing an update and we don’t care about overwriting what is there, and we provide an empty JObject for the meta-data argument. Theoretically we could include other data about the file here, and could open up this ability to the application… but we don’t need that yet and therefore have not. (woo, YAGNI in practise).

With all this in place, we now have the ability to upload the actual images - (Take it as a read that I’ve done the boring web bit unless you really want to see it in which case I’ll write an entry on the subject). Our next items of functionality are the ability to actually list and page through these images whilst applying some sort of filter to those searches. This means we finally get to look at generating views and what features of RavenDB are available to do that with.

2020 © Rob Ashton. ALL Rights Reserved.