Thursday, October 10, 2013

JsonMapper application for CouchDB HTTP data handling

There is a neat application of JsonMapper for CouchDB HTTP data conversion. Couch DB is based on json data. So it is good application area to apply jsonMapper between entity object and serialized object. (Here we see an interesting combination of generic type. Namely by defining generic classes, we can create a flow to pass the entity type to the 'doc' field type at runtime. )

In order to extract entities list from json HTTP output, and do some none standard plumbing of attributes(id must be mapped from _id, rev is from _rev), we can use a single fromJson method.

we define following generic class:

class CouchDBFetchData<T> {
  List<CouchDBFetchRowData<T>> _rows;
  
  List<CouchDBFetchRowData<T>> get rows => _rows;
  void set rows( List<CouchDBFetchRowData<T>> rows) { _rows = rows; }
}

class CouchDBFetchRowData<T> {
  T _doc;
  T get doc => _doc;
  void set doc(T doc) { _doc = doc; }
}

This class does not define all json properties, but they are ignored when json is mapped to the entity object.
then we can apply fromJson to the json output. This is the all things we need to get the list of entities. But unfortunately, right now, since there is a bug (as mentioned in previous post), this will fails. but if it is fixed, this should work.

  Future> getAll() {
    return _getData("/$dbName/_all_docs?include_docs=true")
        .then( (json) {
          if (json != "") {
            CouchDBFetchData<T> data = jsonMapper.fromJson(
              new CouchDBFetchData<T>().runtimeType, json, attr_redirect_map: {'id':'_id', 'rev':'_rev'});
            return data.rows.fold([], (list, CouchDBFetchRowData<T> row)=>list..add(row.doc));
          } else {
            return new List();
          }
        }).catchError((_)=>[]);
  }

here is the original inefficient, inelegant approach.

  Future> getAll() {
    return _getData("/$dbName/_all_docs?include_docs=true")
        .then( (json) {
          if (json != "") {
            Map data = parse(json);
            for (var rowData in data["rows"]) {
              Map map = rowData["doc"];
              map['id'] = map['_id'];
              map.remove('_id');
              map['rev'] = map['_rev'];
              map.remove('_rev');
              String json1 = stringify(map); // ugry
              T t = jsonMapper.fromJson(modelType, json1);
              ts.add(t);
          } else {
            return new List();
          }
        }).catchError((_)=>[]);
  }

No comments:

Post a Comment