Skip to Content

/wp-content/uploads/2015/09/d_shop_blog_logo_799860.jpg

If you are an SAP Employee, please follow us on Jam.


OCaml is an industrial strength programming language supporting functional, imperative and object-oriented styles.


OCaml_Logo.png


Sounds nice, right? OCaml is the next step of the Caml programming language.

Having learning other functional programming languages like Haskell and Erlang, OCaml was the next obvious choice for me…so I decided to start learning it…not an easy task for sure…but really fun and enlighten.

So…no example or demonstration would be complete if we didn’t hook it up with SAP HANA, right? So…let’s go and do it -;)

First, we need to create a Calculation View and call it “FLIGHTS_BY_CARRIER”. It will be composed of two tables, SCARR and SFLIGHT.

First, we need to create a Join object and link the table by MANDT and CARRID. From here select the following fields as output MANDT, CARRID, CARRNAME, PRICE and CURRENCY.

Then create an Aggregation object selecting the fields CARRNAME, PRICE (As Aggregated Column) and CURRENCY. Filter the CURRENCY field by ‘USD’.

Then create a Projection object and select only PRICE and CARRNAME.


On the Semantics object make sure to select “CROSS CLIENT” as the Default Client.

Calculation_View.jpg

Now, switch to the SAP HANA Development View and create a new repository. Call it “Flights”.

Create a new “XS Engine” project and call it “Flights” as well. Link it to the “Flights” repository.

Create an empty “.xsapp” file.

Create a file called “.xsaccess” with the following code.

.xsaccess

{

“exposed” : true,

“authentication” : [ { “method” : “Basic” } ]

}

Finally create a file called “flights.xsodata” with the following code

flights.xsodata

service {

          “Blag/FLIGHTS_BY_CARRIER.calculationview” as “FLIGHTS” keys generate local “Id”;

}


Activate your project and launch it on your browser, you should see something like this…


XSProject.jpg

The SAP HANA part is done…so we can move into the OCaml part…

For first timers, OPAM (the package manager for OCaml can be tricky and sometimes frustrating), so let’s make your lives easier by following this single easy steps…on a terminal session type this…

  • opam init
  • eval `opam config env`
  • opam switch 4.01.0
  • eval `opam config env`
  • opam install core utop core_extended async uri yojson cohttp lwt ezjsonm


It will take a while but by installing all the required packages in a single command, prevents errors from happening.

To code for OCaml I use one of the most awesome editors I have ever found…Geany. It comes almost pre-configured to handle a lot of programming languages, but just to make sure, here’s how I configure it to work with OCaml.


First, create a file and save it as OCaml_HANA.ml


Then, click on the “Choose more build actions” button

Options.jpgThe little half arrow on the right of the brown brick looking button. This will open the following screen

Geany_OCaml.jpg

On Compile put the following

corebuild -pkg yojson,cohttp.async,cohttp.lwt,lwt,ezjsonm “%e.native”

And on Execute put

“./%e.native”

With that, we should be more than ready to start coding 🙂 Copy and paste the following code…

OCaml_HANA.ml

open Core.Std

open Yojson.Basic.Util

open Ezjsonm

let get_definition_from_json json =

  let json = Ezjsonm.from_string(json) in

  let json = Ezjsonm.(find json [“d”;”results”]) in

  let json = Ezjsonm.to_string(json) in

  let json = Yojson.Basic.from_string(json) in

  let json = Yojson.Basic.Util.to_list json in

  let carrname = Yojson.Basic.Util.filter_member “CARRNAME” json in

  let carrname = Yojson.Basic.Util.filter_string carrname in

  let price = Yojson.Basic.Util.filter_member “PRICE” json in

  let price = Yojson.Basic.Util.filter_string price in

  printf “Reading SAP HANA from OCaml\n\n”;

  for i = 0 to List.length(carrname) – 1 do

  printf “%s: %s\n” (List.nth_exn carrname i) (List.nth_exn price i)

done

let fetch uri =

  let cred = Cohttp.Auth.string_of_credential(`Basic(“SYSTEM”, “YourPassword”)) in

  let headers = Cohttp.Header.init() in

  let headers = Cohttp.Header.add headers “Authorization” cred in

  let open Lwt in

  Cohttp_lwt_unix.Client.get ~headers:headers uri

  >>= fun (_,body) ->

  Cohttp_lwt_body.to_string_list body

  >>= fun strings ->

  return(get_definition_from_json (String.concat strings))

let () =

  let hana_uri = Uri.of_string “http://YourServer:8000/Flights/flights.xsodata/FLIGHTS?$format=json

  in Lwt_main.run (fetch hana_uri)


Save your file, press the “Compile the current file” button. The first on the previous images which shows a triangle with an arrow and a ball (all in nice 3D) and then press the “Run or view the current file” button. Last one on the previous image which shows two engines.


OCaml_HANA.jpg

You will notice that it comes pretty fast…

Now…something funny about my code…and that might be because of two simple reasons…

  • I’m still learning OCaml
  • The documentation for external packages is almost non-existent (Actually, I need to browse the GitHub source codes in order to achieve most of the code)

So…the funny thing is that I’m using two different JSON libraries to actually read the ODATA generated by SAP HANA…by using only one I couldn’t manage to get the information that I needed…so using both and extracting pieces from here and there I actually got what I wanted…not so fun when you are doing it…but in the end there a big reward on finally being able to compile it and get the desired output -;)

To report this post you need to login first.

Be the first to leave a comment

You must be Logged on to comment or reply to a post.

Leave a Reply