Encode-Decode

MongoDB receives and sends data in BSON
The driver keeps the data in the language specific datastructures

  • Encode
    driver data --encode--> BSON
  • Decode
    BSON --decode--> driver data

cMQL requirements

cMQL must be able to encode and decode the data in all the supported languages

  • cMQL-j should encode and decode Java Documents <-> BSON (provided by the driver) Clojure maps <-> BSON (custom org.mongodb/bson implementation)
  • cMQL-js
    js objects <-> BSON (provided by the driver) Clojure maps <-> BSON (custom js-bson implementation)

cMQL does that directly from and to BSON,without extra transformation step for perfomance reasons. For example it doesn't convert a Clojure map to a Java Document and then to BSON. cMQL goes directly from Clojure map to BSON.

This required 2 modified versions of BSON than the default that the Java driver and the Javascript driver are using.

Encode in cMQL

Encode is auto-detected.If the user gives a Clojure map,encoder see it and encode accordinally.
Its auto-detected in both cMQL-j and cMQL-js.

User sets the encode methods only for other classes like when using Pojo in Java

Decode

On decode 3 things were important

  • decode directly from BSON
  • save the data in a form that can be used as normal clojure maps/vectors
  • each query to be able to select the decode method

cMQL

  • cMQL-j can return Clojure(clojure-maps/vectors)/Java(java-map/arraylist) data structures
  • cMQL-js can return Clojure(clojure-maps/vectors)/JS(objects/arrays)

to Java

Java default classes to used to save documents and arrays.

  • Documents Java driver uses a Document class,that inside holds a LinkedHashMap
  • Arrays are ArrayLists

This is done by the driver

to Clojure

  • Documents
    Java Document class,that inside holds a Clojure map
    Keys become keywords
  • Arrays are vectors

Documents implement all Clojure interfaces and they behave like Clojure maps. There is no need to take the Clojure map from inside,they are them selves maps.

For example if doc1 is instance of a Document class,that contains inside a Clojure map i can use it as a normal Clojure map,for example i can

(assoc doc1 "a" "b")

We only need to set the registry to be clj-registry,no need to give a return-class, in both cases the return class is a Document class.

Perfomance is very good,as like to native java.

to Javascript

Javascript uses objects for documents and arrays for arrays

to Clojurescript

cMQL has a modified js-bson implementation

2 Options exists for decode

  1. clojure-maps/vectors
  2. beans/vectors

For now they are separated implementations of js-bson

The reason for using bean is perfomance,clojurescript maps is >8 keys,become hashmaps and they are 2x-3x slower in creation from the js-objects

Beans are as fast as js-objects,and allows us to use the bean as if it was a normal clojure map For example we can assoc,get,map etc