Why cMQL for Java

General reasons

  • less code up to 3x
  • simple structure
  • simple notation

Java specific reasons

  • JSON literals
  • simple interop
    • call as a normal static java method
    • get java objects back

Java programmers can use

Here is explained how to use cMQL, to call it from Java code. For more info about cMQL and why is useful see what? and why?.
Java programmers use cMQL-j

How to use

  • write the cMQL queries as seperate project,or add the clojure code inside the java project
  • call them from java

Its very easy to do clojure is hosted language,its created to run on the JVM
See bellow the JavaAppMaven

Examples

Two examples,from the Java Quick Start implemented in cMQL

Insert

cMQL= 540 characters Java = 1010 characters (~2x)

(defn generateNewGrade [student-id class-id]
{:_id (ObjectId.)
:student_id student-id
:class_id class-id
:scores [{:type "exam" :score (* (.nextDouble random) 100)}
{:type "quiz" :score (* (.nextDouble random) 100)}
{:type "homework" :score (* (.nextDouble random) 100)}
{:type "homework" :score (* (.nextDouble random) 100)}]})
(insert :sample_training.grades (generateNewGrade 10000. 1.))
(println "One grade inserted for studentId 10000.")
(insert :sample_training.grades
(mapv (fn [n] (generateNewGrade 10001. (double n))) (range 1 11))
{:ordered false})
(println "Ten grades inserted for studentId 10001.")

Aggregate

cMQL = 345 characters
Java Builder = 1106 characters (~3x)

*Java code can be a bit smaller and go 2.5x,this is the original code from github.

The 2x-3x is the best possible case,if using the supported from Java operators
if operators is not supported(100+ aggregation operators aren't supported) we can go to 4x+

(println "==> 3 most densely populated cities in Texas")
(c-print-all (q :sample_training.zips
(= :state "TX")
(group :city
{:totalPop (sum :pop)})
(sort :!totalPop)
(limit 3)))
(println "==> 3 most popular tags and their posts titles")
(c-print-all (q :sample_training.posts
(unwind :tags)
(group :tags
{:count (sum 1)
:titles (conj-each :title)})
(sort :!count)
(limit 3)
[:tags :count :titles]))

Install dependencies

Install cMQL

Use the dependencies from clojars

  • [org.cmql/cmql-core "0.1.0-SNAPSHOT"]
  • [org.cmql/cmql-j "0.1.0-SNAPSHOT"]

Or lein install using the source code on github.

Install clojureapp

cd clojureapp
lein install

*clojureapp is not on clojars so we need local install to use it from the java-app.

In JavaAppMaven we use cMQL queries with 2 ways

  1. queries as maven dependency
  2. queries written in Clojure inside the maven project

We do this step for the first,to use the queries as dependency

JavaAppMaven

Assuming that you have done the stemps in install cMQL Open the javaappmavenapp with intellijIdea as a normal maven project.

Project structure

2 folders for source code

  • Java
  • Clojure (we put the cMQL clojure code)

Clojure/queries/aggregate_framework.clj

  • example query that we will call from Java code

Java/javaapp/quickstart

Java/Main

  • main Java class,that we use to call the queries

Java/Queries

  • java static functions that wrap clojure functions this is an example of how to wrap clojure function from Java (we could do it from clojure code also)

pom.xml

We have as maven dependency cMQL,cMQL-j and the clojureapp

The clojureapp contains the example queries that we will call from the JavaMavenApp

We also have add some extra resources for maven to find the clojure code

cMQL queries as library

Clojure programmer makes the a Clojure project with the cMQL queries.
Java programmers use it as dependency from the maven project.

  1. Clojure programmer makes a Clojure project with the cMQL queries it can contain clojure and java code
  2. From clojure makes a java class with methods to call those queries
  3. install jar as maven dependency lein install
  4. java user adds the maven depedency in pom.xml
  5. java user just use this class like normal java class

We used this approach in javaappmaven

  1. clojureapp is the clojure project contains clojure and java code and we use leiningen as build tool
  2. clojureapp.interop.quickstart-api creates this Java class
  3. we did lein install
  4. we added in the pom.xml the clojureapp dependency
  5. we import static clojureapp.interop.Quickstart_api.*; and then we called those static methods as normal java static methods

Its very easy to use,and its the best approach,keeping the projects seperate
with their own build tools

If the clojure app needs some shared java files,for example some classes we can add java files inside the clojure app that uses leiningen as build tool. (clojureapp has a java directory with some classes)

cMQL queries in maven project

We can also write the cMQL Clojure code,inside the java maven project.

  1. we make a clojure directory to put the cMQL clojure files and we edit the the pom.xml (see javaappmaven)
  2. we write the cMQL code inside the clojure directory
  3. we make a java wrapper to call the clojure function 2 lines are needed per clojure function that we call see javaapp/Queries
  4. we done with the clojure part,we import static javaapp.Queries.*; and we use the static java methods (the wrappers)

*to make the wrapper in Clojure(like we did on cMQL library example) we need AOT compilation, so here java wrapper was prefered

Run the project

  • Load the data required(see source files for info)
  • Run Main.java

This project is made to show the way we can use cMQL from a maven Java project.

To make a standalone jar for javaappmaven(with all the dependencies)

mvn clean compile assembly:single

Clojureapp

In JavaAppMaven was used as how to use cMQL from Java.

To explore cMQL open the clojureapp(its leiningen project) in intellijdea for example and run the example namespaces

See how to use the Clojureapp to run the cMQL examples.