Mostrando entradas con la etiqueta Ruby. Mostrar todas las entradas
Mostrando entradas con la etiqueta Ruby. Mostrar todas las entradas

sábado, 17 de noviembre de 2012

Ruby joins the SAP HANA party


Believe it or not...I totally forgot to write a blog on how integrate Ruby and SAP HANA...shame on me for sure...and while this is not rocket science, I'm sure there people out there wondering how to do this or struggling to make it work. For all of them...here's how to do it.

First things first, let's define what are we going to do...as I feel bad about forgetting Ruby, I think this should be a really cool blog...so...we're going to use Sinatra (an old time friend of mine) to develop a web application that will connect via ODBC and will present us all the tables contained in the SFLIGHT schema in a dropdown box...after selecting a table, we will have the full content of the table "a la SE16"...

So...we need to install Sinatra...open an CDM session and type the following

Install Sinatra on Ruby
gem install sinatra


Then, we need to install something to read our ODBC connection...where're going to use RDBI, but as it is a native library, we need to do something else before we can actually install it...otherwise we're going to receive an error...

We need to download the Development Kit and extract it, then open an CMD session, go to the folder where you extracted the DevKit and type the following

Install DevKit for Ruby
ruby dk.rb init
ruby dk.rb install

With that, we have all the compilers that we need to make this work. Go to the CMD and type the following

Install RDBI
gem install rdbi-driver-odbc

We should be ready by now...there's one small detail...we might have an ODBC connection for our SAP HANA Server...but...as Ruby works on 32bits, we're going to have a message saying that the driver and the architecture mismatch...to solve it...follow this steps...

Creating an 32bit ODBC
Go to C: --> Windows --> SysWOW64 --> odbcad32.exe


When you create your ODBC connection, make sure to choose the HDBODBC32 driver.

Now...we're more than ready...let's see the Ruby code...

Ruby_SAP_HANA.rb
require 'sinatra'
require 'rdbi-driver-odbc'
 
get '/' do
  body do
    <<-eos
    <div align='center'>
    <h1>Ruby/Sinatra and SAP HANA - Table Browser</h1>
    <form action='/login' method='post'>
      <label for='dsn'>DSN</label><br/>
      <input type='text' name='dsn' /><br />   
      <label for='user'>User</label><br />
      <input type='text' name='user' /><br />
      <label for='password'>Password</label><br />
      <input type='password' name='password' /><br />
      <input type='submit' name='submit' value='Login' />
    </form>
    </div>
    eos
  end
end
 
get '/login_view' do
  $output = "<div align='center'><form action='/table_view' method='post'>"
  $output += "Choose Table <SELECT NAME='tab'>"
  for i in 0...$Tables_Len
    $output += "<option value=#{$Tables[i]}>#{$Tables[i]}</option>"
  end 
  $output += "</option>"
  $output += "<input type='submit' name='submit' value='Show Table' />"
  $output += "</form></div>"
  body $output
end
 
get '/show_table' do
  $output = "<div align='center'><table border='1'><tr>"
  for i in 0...$Fields_Len
    $Fields_Fields = $Fields[i].to_s
    $output += "<th> #{$Fields_Fields} </th>"
  end
  $output += "</tr>"
  for i in 0...$Data_Len
    $output += "<tr>"
    for j in 0...$Fields_Len
      $output += "<td> #{$Data[i][j].to_s} </td>"
    end
    $output += "</tr>"
  end
  $output += "</table></div>"
body $output
end
 
post '/login' do
  $dsn,$user,$password = params[:dsn],params[:user],params[:password]
  "#{do_login}"
  "#{get_tables}"                    
  redirect '/login_view'
end
 
post '/table_view' do
   $tab = params[:tab]
   "#{get_data}"
   redirect '/show_table'
end
 
helpers do
  def do_login
    $dbh = RDBI.connect :ODBC, :db => $dsn, :user => $user,:password => $password
  end
 
  def get_tables
    $rs = $dbh.execute "SELECT table_name from SYS.CS_TABLES_ where schema_name = 'SFLIGHT'"
    $ary = $rs.as(:Array).fetch(:all)
    $Tables = Array.new
 
    for i in 0...$ary.length
      $Tables.push($ary[i][0])
    end
    $Tables_Len = $Tables.length 
  end
 
  def get_data
    $query = "SELECT COLUMN_NAME FROM SYS.CS_COLUMNS_ AS A INNER JOIN SYS.CS_TABLES_ AS B "
    $query += "ON A.TABLE_REF = B.REF_ID WHERE TABLE_NAME = '"
    $query += $tab
    $query += "' AND ABAP_TYPE_ID > 0"
    $rs = $dbh.execute $query
    $ary = $rs.as(:Array).fetch(:all)
    $Fields = Array.new
    $Data = Array.new
 
    for i in 0...$ary.length
      $Fields.push($ary[i][0])
    end
    $Fields_Len = $Fields.length
   
    $query = "SELECT * FROM SFLIGHT." + $tab
    $rs = $dbh.execute $query
    $ary = $rs.as(:Array).fetch(:all)
   
    for i in 0...$ary.length
      $Data.push($ary[i])
    end
    $Data_Len = $Data.length
  end 
end

Let's see some pictures, so you can have a better idea of how this works...


We choose our DSN, pass the Username and Password.

The dropdown box will show us the tables included in the SFLIGHT schema.


We show all the fields with their corresponding data in a nice HTML table.

What do you think? Have I atoned my sins for not writing about Ruby and SAP HANA before?

Greetings,

Blag.

martes, 25 de septiembre de 2012

PowerBuilder and Gateway - The Sinatra style

The other day I was playing with the idea of consuming Gateway from PowerBuilder...so of course, I tried a few things like reading it as a WebService or a Rest Service...none work as Gateway generated OData.


A couple of days ago I read this awesome blog by Mark Bradley called Gateway over PowerBuilder where he was using an OData Service DataWindow...which I didn't found on my PowerBuilder IDE...I contact Mark and he told me he was using a "not released yet" version of PowerBuilder, so my new goal was to find a new way to connect PowerBuilder and Gateway using what I currently had...

I tried a lot of things more...including the WCF Data Services for OData which didn't work at all...

But as part of my job is break my head trying to achieve the most crazy and cool ways of doing things...I decided to took another approach...

I remembered that ruby_odata is capable of consuming Gateway, as I was one of the one that contributed to that project Ruby, Camping and...Gateway? (Sorry...will fix the code as soon as I can...old post)

Then I learned that Sinatra the classy Ruby WebFramework was capable of exposing data as a Rest Service (You need to install also the JSON gem)...so all pieces we falling together...

I wrote a small Ruby/Sinatra script to read from Gateway (For this example, I made the service anonymous...just to type it too often)...BTW...I call it Sinatra_JSON.rb


After launching it, I could check it on my browser...


With that ready...I could move to PowerBuilder...create a Solution --> Target (Specify that you want a window to start) --> And then a RESTFUL Client.





After that, we need to Generate the Proxy...


And create a Grid DataWindow...


We need to define the columns that we're going to retrieve and show in our window.


We create a DataWindow inside our Window (w_window) and a button. We're going to drag & drop the Grid DataWindow into our DataWindow.


Double click the button and paste the following code...


Go to the application and double click on it, paste this code...


We're ready to run our program, and press the "Call Flights" button...


It works! So as a little wrap up...we read the Gateway service using Ruby_OData and expose it as REST service using Sinatra. From PowerBuilder we create a REST client, consume the Sinatra REST service and render it on a Grid DataWindow...

Hope you like it...so far...I guess is the best way to make PowerBuilder and Gateway work until we can put our hands on the latest PowerBuilder release.
The only drawback of course, is that I need to pass the filters manually instead of passing them dynamically...well...next time maybe...

Greetings,

Blag.

miércoles, 7 de diciembre de 2011

Christmas Sale!


Again...up to 30% of discount in my books (printed version) in...

Blag's books in Lulu.com

Available until the first week of January...hurry up and take the deal -;)

Greetings,

Blag.

martes, 27 de septiembre de 2011

Ruby, Camping and...Gateway?


It's been a long time since my last Ruby blog...so I wanted to something nice...instead of emulate any SAP transaction, it was time for me to engage with new SAP technologies, and Gateway really looks promising...so...what's Gateway?
Gateway is based on OData, which allows us to perform CRUD operations on WebService like applications...in other words...it's just awesome technology -;) If you want to find out more, please refer to this homepage on SCN "SAP NetWeaver Gateway Demo System".
So...we can access Gateway using many technologies, for example JavaScript or Java for Blackberry. But for sure, I wanted to go beyond those awesome examples, and searched for other ways to consume Gateway data...on the OData SDK List I found a Ruby gem called Ruby_OData, which works awesome for services like Netflix OData, but didn't work to well for SAP Gateway services...
As you may know...here on SCN, we're like family, so we like to work together on some nice project, so as you can see here...that's what we did -;)

SAP NETWEAVER GATEWAY DEMO SYSTEM


With the gem working, I knew I wanted to blog about it...build a small Ruby application to show how easy is to use the Ruby_OData gem...but of course...having a DOS style black window wasn't very likely...so I decide to use Camping once again -:) and of course...Camping is not very classy...and I think it's not even maintained anymore...so if you're looking for something nicer, you can use Sinatra instead -;)
As I love to say..."Enough talk! Let's go to the source code!"
Camping_Gateway.rb
gem 'ruby_odata'
require 'ruby_odata'

Camping.goes :Camping_Gateway

module Camping_Gateway::Controllers

  class Index < R '/'
    def get
      render :_login
    end
  end
  
  class Login
    def post
      @client = input.client
      @user = input.user
      @password = input.password
      render :_showtable
    end  
  end
  
   class ShowTable 
    def post     
      render :_showtable
    end
  end 
end 

module Camping_Gateway::Views
  def layout
    html do
      head do
        title {"Camping and Gateway - Flight Example"}
      end
      body { _login }
    end
  end

  def _login
    form:action => R(Login), :method => 'post' do
      h1 {"Camping and Gateway - Flight Example"}

      label 'Client ', :for => 'client';
      input :name => 'client', :type => 'text'; br
      label 'User ', :for => 'user';
      input :name => 'user', :type => 'text'; br
      label 'Password ', :for => 'password';
      input :name => 'password', :type => 'password'; br      
      
      input :type => 'submit', :name => 'login', :value => 'Login'
    end
  end

  def _showtable
    svc = OData::Service.new "http://gw.esworkplace.sap.com/sap/opu/sdata/sap/DEMO_FLIGHT",
                             {:username => @user, :password=> @password, 
                              :additional_params=> {'sap-client'=>@client.to_i}}
    svc.z_demo_flightCollection
    flight = svc.execute

    $Data_Names = Array.new
    $Data_Fields = Array.new
    $Data_Split = Array.new
    
    $Data_Names.push("Airline")       #airline
    $Data_Names.push("City From")     #cityfrom
    $Data_Names.push("Airport From")  #airportfr
    $Data_Names.push("Currency")      #curr_iso
    $Data_Names.push("City To")       #cityto
    $Data_Names.push("Airport To")    #airportto    

    for flights in flight do
      puts flights.airline
      $Data_Fields.push(flights.airline + "|" + flights.cityfrom + "|" + 
                        flights.airportfr + "|" + flights.curr_iso + "|" + 
                        flights.cityto + "|" + flights.airportto)
    end    

    $Fields_Len = $Data_Names.length
    $Data_Len = $Data_Fields.length

    table.sample! :cellspacing => 0, :cellpadding => 2 do
      thead do
        tr do
          for i in 0...$Fields_Len
            th "#{$Data_Names[i]}"
          end          
        end
      end
      for i in 0...$Data_Len
        tbody do
          tr do
            $Data_Split = $Data_Fields[i].split("|")
            for i in 0...$Fields_Len
              td "#{$Data_Split[i].to_s.strip}"
            end
          end
        end
      end
    end
  end 
end
To run this example, we need to provide only 3 simple parameters:
Client = 800
Username = GW@ESW
Password = ESW4GW






I know what you're going to tell me after you read the source code...why I'm taking the work of reading the date, putting them on an array and looping that? I know I just could read the field from the model and all that...but...for some reason that I still need to discover...the filtering doesn't work as I expected...for example...I should be able to pass a filter to only select the CITYTO = ' NEW YORK', but it doesn't work even when I don't have any errors...so my approach here (and that's for another blog), it to have all the information stored internally to be able to do the filtering after calling the Gateway service...so...if you're an SAP Gateway expert...please let me how to make the filter work -:( Because, I know that if I pass the VALUE, SCHME_ID and SCHEME_AGENCY_ID it's going to work, but only for 1 record...I want a better filter -;)
Hope you enjoy this one...and see you soon with more Gateway coolness!

Greetings,

Blag.

martes, 30 de noviembre de 2010

Chrstimas Sale!


Starting today and for all December...get a 25% discount in all my books!

Blag en Lulu.com

Go get this awesome sale!

Greetings,

Blag.

sábado, 23 de mayo de 2009

Blag's Flex 3 compiler - Executable edition


Last year, I wrote a blog on SCN titled Blag's Flex 3 Compiler which was basically, a Ruby application using WxRuby for the GUI and Flex 3 SDK to compile Flex and AIR applications.

You may wondering why I'm posting again after 1 long year...easy...I finally could get an .EXE version working.

When I first developed the compiler I tried to build an .EXE using RubyScript2Exe and Exerb, which are amazing Ruby to .EXE scripts...but both failed when I came to WxRuby...

A couple of days ago...I found Ocra. Gotta say this...Ocra rules badly! It's fast, compiles anything and most important...keep the generated .EXE files relatively very small...

So, here the link for the compiler...And don't forget to read the README file -;)


Greetings,

Blag.

martes, 17 de febrero de 2009

The Art of Programming Ruby


I just published my second book in English...


.

Greetings,

Blag.

viernes, 5 de diciembre de 2008

Looking for the perfect Ruby IDE


I consider myself a Ruby fan...That's why I'm always looking for news and of course...IDE's.

My first approach was FreeRide, a Ruby based IDE. What I love about this IDE it it's simplicity...While some people are getting used to fancy RAD tools, I like to keep things as simple as possible...FreeRide offers this.


Second try was Ruby in Steel, which is free in it's personal edition. I have never been a huge fan of Visual Studio even when I got some C# skills...Despise that, I decide to give this IDE a try...Installation was quick and smooth...However, as I already had Ruby installed on my laptop, I decided to skip it from the installation for later configuration...Sad surprise when I pointed to my Ruby installation folder...Ruby in Steel didn't accept it...According to the message, I needed Ruby to be installed on Program Files folder, while I have it under Programacion folder. Bad thing, as I got no plans on uninstalling my current configuration...


My last attempt was NetBeans 6.5 which is currently bundling Ruby/Rails, Groovy/Grails, C/C++, Java/JavaME/JavaFX and PHP (I wonder why left out Python and Perl)...This was a real pleasant surprise...NetBeans had done an excellent job...I really love the IDE and sure love the Ruby support which is run under JRuby...I could installed all my beloved gems and start working...Highly recommended -:)


Now...I know what you're thinking..."Hey Blag...Haven't you tried Eclipse?" Sure I did, but doesn't think it was necessary to put it here...I use Eclipse for my Flex development and wanted to keep it that way...

Also...There are a plethora of IDE's out there...But those three we're the most important to me...Which are yours?

Greetings,

Blag.