Wednesday 22 January 2014

RavenDB Import / Export in code

The recommended way of doing backups automatically is using Smuggler on the server in a scheduled job or if you do manual backups and restores it’s through the RavenDB management studio but what happens if you’ve not got the ability to do either of those? It’s time to build in import/export functionality into your application.

This was a requirement that I was looking at a while back and then when I did some further investigation more recently I had found a thread on the RavenDB Google group and the associated pull request to allow for smuggling functionality without the http server running; problem solved! So how can it be used?

The changes that were made extracted out an interface ISmugglerApi to allow for a common mechanism for both the server/http version and the internal embedded implementations.

So how do we backup? This is an implementation from an MVC application perspective. Context is a way to determine the difference in implementation if you require to develop and/or deploy onto the different platforms.

public async Task<ActionResult> Backup()
{
    SmugglerOptions smugglerOptions = new SmugglerOptions { BackupPath = Server.MapPath(ServerMapPath) };
    switch (Context)
    {
        case Context.Embedded:
            DataDumper dumper = new DataDumper(((EmbeddableDocumentStore)MvcApplication.Store).DocumentDatabase, smugglerOptions);
            var embeddedExport = dumper.ExportData(null, smugglerOptions, false);
            await embeddedExport;
            break;

        case Context.Server:
            var connectionStringOptions = new RavenConnectionStringOptions
            {
                ApiKey = “insert ApiKey”,
                DefaultDatabase = “db_name,
                Url = “http://localhost:8080”
            };

            var smugglerApi = new SmugglerApi(smugglerOptions, connectionStringOptions);
            var serverExport = smugglerApi.ExportData(null, smugglerOptions, false);
            await serverExport;
            break;
    }

    return File(Server.MapPath(ServerMapPath), "application/binary", "backup.dump");
}

For the embedded version you specify the mapped server path on the local machine at the location the server will write the file to, initiate a new instance of the DataDumper class and call ExportData. There is no need for a stream or to get the incremental flag for this basic usage.

The hosted server version you have to specify they api key, database name and the url of the server to use. These are all bit of information you should know if you or can get access to if you are developing in this way. Once this is established you can call ExportData in the same way as the DataDumper call.

Restoring the backed up file is very similar but in reverse.

public async Task<ActionResult> Restore()
{
    SmugglerOptions smugglerOptions = new SmugglerOptions { BackupPath = Server.MapPath(ServerMapPath) };
    switch (Context)
    {
        case Context.Embedded:
            DataDumper dumper = new DataDumper(((EmbeddableDocumentStore)MvcApplication.Store).DocumentDatabase, smugglerOptions);
            var embeddedImport = dumper.ImportData(smugglerOptions);
            await embeddedImport;
            break;

        case Context.Server:
            var connectionStringOptions = new RavenConnectionStringOptions
            {
                ApiKey = “insert ApiKey”,
                DefaultDatabase = “db_name”,
                Url = “http://localhost:8080”
            };

            var smugglerApi = new SmugglerApi(smugglerOptions, connectionStringOptions);
            var serverImport = smugglerApi.ImportData(smugglerOptions);
            await serverImport;
            break;
    }

    return View("Index");
}

There are many other options which can be used but the above is one of the simplest implementations.

When I was doing some research on how to use this mechanism there were no examples I could find in the blogosphere however reading the the code and looking at the unit tests of the RavenDB source it was enough of an example to work with. I’d highly recommend reading the unit tests and the source of open source if you are struggling to find examples of how to use it; it is good documentation especially if the mechanism you are trying to use is used in the software itself.

Sunday 5 January 2014

New Years Resolution Gym Goers; Don’t Join!

I am writing to all the people who’s new years resolution is to “get fit” or “lose weight” and this usually means they think they should join a gym … don’t! Well not initially anyway. If you’re already a member of a gym then I’m sure you can relate to this.

Let me explain why I think you shouldn’t join a gym …

The way this usually works is people think they need to join a gym, so they join at £xx per month and get locked into a 12 month starter contract. They then start to go in January with the aim to go 3 to 4 times a week and do this class and that class. They do it for maybe two to three weeks but then work gets in the way, they remember they want to go to the pub and socialise instead of doing squats and crunches and before they know it they’re paying their membership fees so they can say to their friends “I’m a member of a gym”.

Don’t get me wrong there are people out there who start in January, get fit, get ripped, be happy etc. but a majority flounder and give up.

So people end up paying a lot of money for not going to the gym and for January the people who take it up and stop in February just annoy and get in the way of regular gym goers.

Let me be fully clear I am a member of a gym and have been for many years; although it wouldn’t show looking at me. I dip in for a few weeks/months at a time and then something comes up etc. and don’t go for a while so I look at the issue from both sides depending on where I am.

So what can people do to get fit and save money?

To get fit you don’t need to join a gym although joining eventually can help. You can start off by doing free activities such as running. You can get a number of apps now a days which will help you train from couch to xkm and apps which will track you such as RunKeeper. If you want to run with people there are many ParkRuns world wide which you can sign up for and go to for free.

If you want to be more serious about training then look to get a personal trainer who comes to your house and can train you in the garden or local park. This way you are paying purely for their time and not paying the gym *and* a personal trainer.

If once you get to the point where you want to join a gym and you’re already getting fit and have built in the time into your weekly schedule then please do. When you do try not to feel self conscious about going to the gym if you aren’t model thin or can only lift a couple of kgs people are there for themselves and don’t care what others are doing. So take some music and lose yourself in the exercise.

It doesn’t matter if you train at the gym or not but you do feel better for doing exercise so I encourage you to keep with your new years resolution.

Happy exercising and money saving in 2014!