danielwertheim

danielwertheim


notes from a passionate developer

Share


Sections


Tags


Disclaimer

This is a personal blog. The opinions expressed here represent my own and not those of my employer, nor current or previous. All content is published "as is", without warranty of any kind and I don't take any responsibility and can't be liable for any claims, damages or other liabilities that might be caused by the content.

MyCouch - New fix release & some words about meta-data

I usually don’t blog about when I do a new release of MyCouch – THE async .Net driver for CouchDB and Cloudant; so why this time? Well, because it’s a rather embarrassing little fix, in the sense:

Why did I not support this earlier?

Yeah, why didn’t I? Let me try and explain why but first, lets look at what the fix actually solves.

I got a report stating that the driver could not handle CouchDB _ids with chars in the need of encoding, e.g. "persons/1"

using (var client = new MyCouchClient("http://localhost:5984/foo"))
{
  var db = await client.Database.PutAsync();

  var put = await client.Entities.PutAsync(
      new Person { Id = "persons/1", Name = "Daniel" });

  var get = await client.Entities.GetAsync(put.Id);
}

With the release of v2.4.2 of MyCouch, this is now possible. Please note though, that (as I see it) Microsoft has a flaw in their HttpClient distributed via NuGet, for getting HttpClient in .Net4.0, so to support this in .Net4.0, you have to do an ugly workaround as documented here: Support for _id in the need of encoding

Why was this not supported before?

Easy, no one has needed it. Why? Well, I do know that some storage solutions uses the Id to indicate “type of entity” or “collection”. If you look at the end-point it makes a bit sense perhaps, that you have the database/collection/id. How-ever, CouchDB, does not have any built in support for having “types of documents”. All documents are siblings and stored in the same database. Usually, you deal with this in your maps (as in map & reduce) by adding an attribute to your documents, indicating what kind of document it is. This has been supported from the beginning in MyCouch as it automatically injects a$doctypeproperty that you can use for this. You can also override the $doctype either by hooking in a custom convention or by using attributes.

How-to override $doctype and provide more meta-data using attributes

You can override the $doctype and-also provide other meta-data, like a namespace or a version of the document by the use of an attribute.

[Document(
  DocType = "MyType",
  DocNamespace = "MyNamespace",
  DocVersion = "1.2.1")]
public class ModelEntityWithMeta
{
  public string Id { get; set; }
  public string Rev { get; set; }
  public string Value { get; set; }
}

How-to override $doctype and provide more meta-data using a serialization configuration

When you construct e.g. your MyCouchClient you can pass in a custom MyCouchClientBootstrapper. Inside of it, there’s a member SerializationConfigurationFn that determines the configurations to use for the serialization. On that, there’s a member Conventions, that has some ISerializationConvention you can assign your own conventions to. The default implementation looks like this:

public class SerializationConventions
{
    public ISerializationConvention DocType { get; set; }
    public ISerializationConvention DocNamespace { get; set; }
    public ISerializationConvention DocVersion { get; set; }

    public virtual bool HasConventions
    {
        get { return ...; }
    }

    public SerializationConventions()
    {
        DocType = new StringSerializationConvention(
            "$doctype",
            m => !m.IsAnonymous ? m.DocType.ToCamelCase() : null);

        DocNamespace = new StringSerializationConvention(
            "$docns",
            m => m.DocNamespace);

        DocVersion = new StringSerializationConvention(
            "$docver",
            m => m.DocVersion);
    }
}

That’s all for now. Hope you find MyCouch useful.

Cheers,

//Daniel

View Comments