Bryan hearts Raven DB

I’ll start with the punch line. RavenDB just rocked my world. Two things stick out: 

  1. It combines a database with an ORM – It’s as if Ayende said “I’m tired of working on the whole ORM thing. They only exist because SQL databases aren’t solving the right problems. Let’s just combine SQL  and the ORM and simplify everybody’s life.”
  2. It’s extremely approachable, even for non-database guys – It took me less than 30 minutes to get up and running.

How did I jump to those conclusions?

I have a confession to make. I’m not a database guy. In fact, when I’m prototyping, I tend to go to great lengths to avoid using databases. Sometimes, these workarounds are sane.  Using a disk based key/value store isn’t so bad.  Tonight, however, I was going down an insane path.

Some background

Our blog content is created in a CMS built by our colleagues at Newsvine. All of our other content is in our custom CMS (named Workbench). As you might expect, our editors don’t care which CMS their content is in. They just want to use their content however they wish.

Tonight, I prototyped a process that consumes blog feeds from Newsvine and creates stubs in Workbench for each blog post. In Workbench lingo, these stubs are called “teases.”  So far so good.

It started to get more interesting I wanted to make sure that:

  1. I didn’t create more than one tease for each blog post
  2. When blog posts are updated, the teases are updated

I’m guessing the average developer would create a link table in a database to maintain a mapping between the two systems. Not me. Instead I charged down a path of great difficulty. In a nutshell, I relied upon a very fragile folder path and naming convention in Workbench to infer a mapping between Workbench and Newsvine. My approach was fraught with peril since:

  1. Humans can change the names and folders of things (and they do!)
  2. There was really no way for me to track changes to posts and appropriately update the teases

Raven to the rescue

Ninety minutes into the madness, I decided to give Raven a whirl (a couple of other folks here have been doing some really great stuff with it). Within 30 minutes, my stuff was working. Most impressive (not me, Raven). For the truly interested, here’s the Raven stuff from my prototype. It was incredibly easy. 

 

Code Snippet
  1.  
  2. public class NewsvineBlogPostLink
  3. {
  4.     public string Id { get; set; }
  5.     public int WorkbenchId { get; set; }
  6.     public DateTimeOffset PublishDateTime { get; set; }
  7. }
  8.  
  9. class RavenNewsvineBlogPostToTeaseLinkManager : INewsvineBlogPostToTeaseLinkManager
  10. {
  11.  
  12.     private DocumentStore store;
  13.  
  14.     public RavenNewsvineBlogPostToTeaseLinkManager(DocumentStore store)
  15.     {
  16.         this.store = store;
  17.     }
  18.  
  19.     public bool IsInWorkbench(NewsvineBlogPost post)
  20.     {
  21.         var link = LoadLink(post);
  22.         return link != null ? true : false;
  23.     }
  24.  
  25.     private NewsvineBlogPostLink LoadLink(NewsvineBlogPost post)
  26.     {
  27.         using (var session = store.OpenSession())
  28.         {
  29.             var link = session.Load<NewsvineBlogPostLink>("newsvinepostlinks/" + post.NewsvineId);
  30.             return link;
  31.         }
  32.     }
  33.  
  34.     public bool HasPostBeenUpdated(NewsvineBlogPost post)
  35.     {
  36.         var link = LoadLink(post);
  37.         return link != null ? true : false;
  38.     }
  39.  
  40.     public int GetTeaseIdForPost(NewsvineBlogPost post)
  41.     {
  42.         var link = LoadLink(post);
  43.         return link != null ? link.WorkbenchId : -1;
  44.     }
  45.  
  46.     public void LinkPostToTease(NewsvineBlogPost post, int teaseId)
  47.     {
  48.         using (var session = store.OpenSession())
  49.         {
  50.             var link = new NewsvineBlogPostLink
  51.             {
  52.                 Id = "newsvinepostlinks/" + post.NewsvineId.ToString(),
  53.                 WorkbenchId = teaseId,
  54.                 PublishDateTime = post.PublishDateTime
  55.             };
  56.             session.Store(link);
  57.             session.SaveChanges();
  58.         }
  59.     }
  60. }

Discuss this post

Oddly enough, this post prompted a conversation around here on why ternary operators might be evil. Specifically, I could have just returned:

return link != null;

Of course, that same developer also showed a way to make things more confusing. I was much impressed:

return (((((0x0000A*0x002)/(0x0F+(-0x000000000B)))<<(int)2.0)-0x4)>>4)&(!(link == null))

Nothing like a few hex values and bit shifting to enhance readability.

    Reply#1 - Mon Jul 11, 2011 11:31 AM EDT

    Nice post, Raven is indeed very nice to work with and it has some really interesting technical bits in it (Lucene, Json.NET, Esent etc).

    I agree with the comment about ternary operators, they can be abused. But you should use ReSharper, I'm sure it tells you about things like this.

      Reply#2 - Fri Jul 22, 2011 5:11 PM EDT

      Hey Matt,

      We're always interested to see what others are doing with RavenDB. Anything you can share?

       

       

        Reply#3 - Mon Aug 1, 2011 11:59 PM EDT
        markDeleted

        Mark; a late reply, but yes this did get rolled out, after going through some modifications.

          Reply#5 - Mon Feb 20, 2012 2:14 AM EST
          You're in Easy Mode. If you prefer, you can use XHTML Mode instead.
          As a new user, you may notice a few temporary content restrictions. Click here for more info.