Saturday, November 17, 2012

Ruby se une a la fiesta de SAP HANA

Creanlo o no...me habia olvidado totalmente de escribir un blog de como integrar Ruby y SAP HANA...una verguenza sin duda...y mientras esto no es nada de otro mundo, estoy seguro que hay mucha gente preguntandose como hacer esto o luchando para hacerlo funcionar. Para todos ellos...aqui esta como hacerlo.

Primero lo primero, vamos a definir que es lo que vamos a hacer...como me siento mal por haberme olvidado de Ruby, pienso que este deberia ser un blog realmente bueno...asi que...vamos a utilizar Sinatra (un viejo amigo mio) para desarrollar una aplicacion web que se va a conectar via ODBC y va a presentarnos todas las tablas contenidas en el esquema SFLIGHT en un dropdown box...luego de seleccionar la tabla, tendremos todo el contenido de la tabla "a la SE16"...

Asi que...necesitamos instalar Sinatra...abran una sesion del CDM y escriban lo siguiente

Instalar Sinatra en Ruby
gem install sinatra

Luego, necesitamos hacer algo para leer nuestra conexion ODBC...vamos a utilizar RDBI, pero como es una libreria nativa, necesitamos hacer algo antes de poder instalarla...de otro modo...recibiremos un error.

Necesitamos descargar el Development Kit y extraerlo, luego abrir una sesion de CMD, ir a la carpeta donde esta el DevKit y escribir lo siguiente

Instalar DevKit para Ruby
ruby dk.rb init
ruby dk.rb install

Con eso, tenemos todos los compiladores que necesitamos para hacer que esto funcione. Vayan al CMD y escriban lo siguiente

Instalar RDBI
gem install rdbi-driver-odbc

Con esto, ya deberiamos estar listos...solo hay un pequeno detalle...debemos tener una conexion ODBC para nuestro servidor SAP HANA...pero...como Ruby trabaja con 32bits, vamos a recibir un mensaje diciendo que el driver y la arquitectura no son compatibles...para resolverlo...sigan estos pasos...

Creando un ODBC de 32bits
Vayan a C: --> Windows --> SysWOW64 --> odbcad32.exe

Cuando creen su conexion ODBC, asegurense de escoger el driver HDBODBC32.

Ahora...estamos mas que listos...veamos el codigo Ruby...

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

Veamos algunas imagenes, para que tengan una mejor idea de como trabaja esto...


Escogemos nuestro DSN, pasamos el nombre de usuario y Password.

El dropdown box nos mostrara todas las tablas incluidas en el esquema SFLIGHT.


Mostramos todos los campos con su data correspondiente en una bonita tabla HTML.

Que piensan? He limpiado mis pecados por no haber escrito antes sobre Ruby y SAP HANA?

Saludos,

Blag.

No comments: