The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

   BridgeServer.pm - ODBC API for network clients.

SYNOPSIS

    use UnixODBC::BridgeServer;
    UnixODBC::BridgeServer::main();

DESCRIPTION

UnixODBC::BridgeServer provides an object oriented API for communicating with ODBC driver managers on network systems. A UnixODBC::BridgeServer client is a subclass of RPC::PlClient, and communicates with a UnixODBC::BridgeServer daemon (see "man odbcbridge") on the DBMS server system using Remote Procedure Calls. UnixODBC::BridgeServer provides a network interface to the API in UnixODBC.pm. The UnixODBC manual page describes those functions.

Here is a client that uses the UnixODBC::BridgeServer API.

  #! /usr/bin/perl

  use RPC::PlClient;
  use UnixODBC qw (:all);
  use UnixODBC::BridgeServer;

  #
  # Edit for the Host Address, DSN, TableName, UserName and PassWord of 
  # the remote data source.
  #
  my $HostAddress = '127.0.0.1';
  my $DSN = 'Data_Source_Name';
  my $TableName = 'Table_Name';
  my $UserName = 'User_Name';
  my $PassWord = 'Password';

  # Port address used by client and odbcbridge daemon.

  my $Port = 9999;

  # Maximum field length.  The RPC::PlServer POD documentation describes
  # how to change this.

  my $MaxFieldLength = 65535;

  # ODBC Handles

  my $evh = 0;  # Environment Handle
  my $cnh = 0;  # Connection Handle
  my $sth = 0;  # Statement Handle

  # Return values for sql_get_diag_rec 

  my ($r, $sqlstate, $native, $text, $textlen);

  # SQL Query Text

  my $query = "select \* from $TableName\;";

  # Rows and columns in the result set

  my ($nrows, $ncols);

  # Create a RPC network client object.  This manages the 
  # network connection.

  my $client = 
      eval { RPC::PlClient->new('peeraddr' => $HostAddress,
                          'peerport' => $Port,
                          'application' => 'UnixODBC::BridgeServer',
                          'version' => $UnixODBC::VERSION,
                          'user' => $UserName,
                          'password' => $PassWord) }
     or do {
        print "Failed to make first connection: $@\n";
        exit 1;
     };

  # Create the BridgeClient object.

  my $c = $client -> ClientObject ('BridgeAPI', 'new');

  # Uncomment if you want the Driver Manager to log the ODBC 
  # function calls.  Also uncomment the call to dm_log_close,
  # below.

  # my $ODBCLogFile = '/tmp/sampleclient.log';
  # $c -> dm_log_open ('UnixODBC Bridge Sample Client', $ODBCLogFile);

  # Allocate an environment handle.

  $evh =  $c -> sql_alloc_env ();
  if (defined $evh) { 
      $r = $c -> 
          sql_set_env_attr ($evh, $SQL_ATTR_ODBC_VERSION, $SQL_OV_ODBC2, 0);
  } else {
      ($r, $sqlstate, $native, $text, $textlen) = 
          $c -> sql_get_diag_rec ($SQL_HANDLE_ENV, $evh, 1, 255);
      print "\nsql_alloc_handle: $r, $text, $textlen\n";
      exit 1;
  }

  # Allocate a connection handle.

  $cnh = $c -> sql_alloc_handle ($SQL_HANDLE_DBC, $evh);

  # Connect to the data source.

  $r = $c -> sql_connect ($cnh, $DSN, length($DSN),
                          $UserName, length($UserName), 
                          $PassWord, length($PassWord), 0);
  if ($r != 0) {
      ($r, $sqlstate, $native, $text, $textlen) = 
          $c -> sql_get_diag_rec ($SQL_HANDLE_DBC, $cnh, 1, 255);
      print "\nconnect: $r, $text, $textlen\n";
  }

  # Allocate a statement handle.

  $sth = $c -> sql_alloc_handle ($SQL_HANDLE_STMT, $cnh);
  if (! defined $sth) {
      ($r, $sqlstate, $native, $text, $textlen) = 
          $c -> sql_get_diag_rec ($SQL_HANDLE_DBC, $cnh, 1, 255);
      print "\nsql_alloc_handle sth: $r, $text, $textlen\n";
  }

  # Query the remote DBMS.

  $r = $c -> sql_exec_direct ($sth, $query, length ($query));
  if ($r != 0) {
      ($r, $sqlstate, $native, $text, $textlen) = 
          $c -> sql_get_diag_rec ($SQL_HANDLE_STMT, $sth, 1, 255);
      print "\nsql_exec_direct: $r, $text, $textlen\n";
  }

  # Get the number of columns in the result set.

  ($r, $ncols) = $c -> sql_num_result_columns ($sth);
  if ($r != 0) {
      ($r, $sqlstate, $native, $text, $textlen) = 
          $c -> sql_get_diag_rec ($SQL_HANDLE_STMT, $sth, 1, 255);
      print "\nsql_num_result_columns: $r, $text, $textlen\n";
  }

  # Get the number of rows in the result set.

  ($r, $nrows) = $c -> sql_row_count ($sth);
  if ($r != 0) {
      ($r, $sqlstate, $native, $text, $textlen) = 
          $c -> sql_get_diag_rec ($SQL_HANDLE_STMT, $sth, 1, 255);
      print "\nsql_num_result_columns: $r, $text, $textlen\n";
  }

  # Print the number of rows and columns in the result set.

  print "\n$nrows rows, $ncols columns\n";

  # Fetch each row and each column's contents.

  while (1) {
    $r = $c -> sql_fetch ($sth);
    last if $r == $SQL_NO_DATA;
    foreach my $colno (1..$ncols) {
        ($r, $text, $textlen) = 
            $c -> sql_get_data ($sth, $colno, $SQL_C_CHAR, $MaxFieldLength);
        print "$text\t";
    }
    print "\n";
  }

  # De-allocate the ODBC handles.

  $r = $c -> sql_free_handle ($SQL_HANDLE_STMT, $sth);
  if ($r != 0) {
      ($r, $sqlstate, $native, $text, $textlen) = 
          $c -> sql_get_diag_rec ($SQL_HANDLE_DBC, $cnh, 1, 255);
      print "\nfree_handle sth: $r, $text, $textlen\n";
  }

  $r = $c -> sql_disconnect ($cnh);
  if ($r != 0) {
      ($r, $sqlstate, $native, $text, $textlen) = 
          $c -> sql_get_diag_rec ($SQL_HANDLE_DBC, $cnh, 1, 255);
      print "\nconnect: $r, $text, $textlen\n";
  }

  $r = $c -> sql_free_connect ($cnh);
  if ($r != 0) {
      ($r, $sqlstate, $native, $text, $textlen) = 
          $c -> sql_get_diag_rec ($SQL_HANDLE_ENV, $evh, 1, 255);
      print "\nfree_connect: $r, $text, $textlen\n";
  }

  $r = $c -> sql_free_handle ($SQL_HANDLE_ENV, $evh);
  if ($r != 0) {
      ($r, $sqlstate, $native, $text, $textlen) = 
          $c -> sql_get_diag_rec ($SQL_HANDLE_ENV, $evh, 1, 255);
      print "\nfree_connect: $r, $text, $textlen\n";
  }

  # $c -> dm_log_close;

Application Programming Interface

ODBC Return Values

The ODBC API defines these return values for the status of function calls.

  Perl Variable                   Numeric Value
  -------------                   -------------
  $SQL_NULL_DATA                  -1
  $SQL_DATA_AT_EXEC               -2
  $SQL_SUCCESS                    0
  $SQL_SUCCESS_WITH_INFO          1
  $SQL_NO_DATA                    100
  $SQL_NO_DATA_FOUND              100
  $SQL_ERROR                      -1
  $SQL_INVALID_HANDLE             -2
  $SQL_STILL_EXECUTING            2
  $SQL_NEED_DATA                  99

Methods in the UnixODBC::BridgeServer API

$c is an instance of a UnixODBC client that has established a network connection to a UnixODBC server. The example scripts show how to construct the client object.

dm_log_open (application_name, log_file_name)

  Opens a log file on the remote server.  You must have 
  write privileges in that directory.

  Returns 0;

  $c -> dm_log_open ('ODBC Bridge', '/tmp/odbcbridge.log');

dm_log_close

  Closes the log file on the remote server.

  $c -> dm_log_close;

sql_alloc_connect (environment_handle)

  Returns a new connection handle, or undef on error.

  $cnh = $c -> sql_alloc_connect ($evh);

sql_alloc_env ()

  Returns a new environment handle, or undef on error.

  $evh = $c -> sql_alloc_env ();

sql_alloc_handle (handle_type, parent_handle)

  Returns the new handle, or undef on error.

  # Allocate an environment handle

  $evh = $c -> sql_alloc_handle ($SQL_HANDLE_ENV, $SQL_NULL_HANDLE);

  # Allocate a connection handle

  $cnh = $c -> sql_alloc_handle ($SQL_HANDLE_DBC, $evh);

  # Allocate a statement handle

  $sth = $c -> sql_alloc_handle ($SQL_HANDLE_STMT, $cnh);

sql_cancel (statement_handle)

  Returns the ODBC API return value.

  $r = $c -> sql_cancel ($sth);

sql_col_attribute (statement_handle, column_number, attribute, maxlength)

  Returns a list of
  - SQL return value
  - Text attribute if any
  - Length of text attribute
  - Numeric attribute

  ($r, $text, $textlen, $num) = 
      $c -> sql_col_attribute ($sth, 1, $SQL_COLUMN_NAME, 255);

sql_columns (statement_handle, catalog_name, catalog_name_length, schema_name, schema_name_length, table_name, table_name_length, column_name, column_name_length)

  Returns the ODBC API return value.

  # Retrieve and print all column names for table named $table
  $r = $c -> sql_columns ($sth, '', 0, '', 0, 
                          "$table", length($table), '' 0);
  while (1) {
    $r = $c -> sql_fetch ($sth);
    last if $r == $SQL_NO_DATA;
    if ($r != $SQL_SUCCESS) {
      ($r, $sqlstate, $native, $text, $textlen) = 
        $c -> sql_get_diag_rec ($SQL_HANDLE_STMT, $sth, 1, 255);
      print "[sql_fetch]$text\n";
      return 1;
    } 

    # Column names are the fourth column of the result set.
    ($r, $text, $textlen) = 
      $c -> sql_get_data ($sth, 4, $SQL_C_CHAR, 255);
    last if $r == $SQL_NO_DATA;
    print "$text\n";
    if ($r != $SQL_SUCCESS) {
       ($r, $sqlstate, $native, $text, $textlen) = 
        $c -> sql_get_diag_rec ($SQL_HANDLE_STMT, $sth, 1, 255);
      print "[sql_get_data]$text\n";
      return 1;
    } 
  }

sql_connect (connection_handle, data_source_name, user_name, user_name_length, password, password_length)

  Returns the ODBC API return value.

  $r = $c -> sql_connect ($cnh, 'Customers', 
                          'joe', length('joe'),
                          'password', length('password'));

sql_data_sources (environment_handle, orientation, maximum_dsn_name_length, maximimu_driver_name_length);

  Returns a list of
  - ODBC API return value.
  - DSN name.
  - Length of DSN name text.
  - Name of DBMS Driver for DSN.
  - Length of driver text.

  ($r, $dsnname, $dsnlength, $drivername, $drivernamelength) = 
  $c -> sql_data_sources ( $evh, $SQL_FETCH_FIRST, 
                           $messagelength1, 
                           $messagelength2 );

sql_describe_col (statement_handle, column_number, maxlength)

  Returns a list of 
  - SQL API return value
  - Column name
  - Name length
  - Data type
  - Size
  - Decimal digits
  - Nullable

  ($r, $name, $namelength, $type, $size, $decimal_digits, $nullable) 
    = $c -> sql_describe_col ($sth, 1, 255);

sql_disconnect (connection_handle)

  Returns the ODBC API return value.

  $r = sql_disconnect ($cnh);

sql_drivers (environment_handle, orientation, description_maximum_length, attribute_maximum_length)

  Returns a list of: 
  - SQL API return value
  - Driver description string
  - Driver description string length
  - Attribute description string
  - Attribute description string length

  ($r, $desc, $desc_len, $attr, $attr_len) =
    sql_drivers ($evh, $order, $desc_max_len, $attr_max_len);

sql_end_tran (handle_type, handle, completion_type)

  Returns the ODBC API return value.

  $r = sql_end_tran ($SQL_HANDLE_STMT, $sth, 0);

sql_error (environment_handle, connection_handle, statement_handle, maxlength)

  Returns an ODBC error message.

  ($r, $sqlstate, $native, $text, $textlen) = 
    $c -> sql_error ($evh, $cnh, $sth, $maxlength);

sql_exec_direct (statement_handle, query, query_length)

  Returns the ODBC SQL return value

  $r = $c -> sql_exec_direct ($sth, $query, length ($query));

sql_execute (statement_handle)

  Returns the ODBC API return value

  $r = $c -> sql_execute ($sth);

sql_fetch (statement_handle)

  Returns the ODBC API return value.

  $r = sql_fetch ($sth);

sql_fetch_scroll (statement_handle, orientation, offset);

  Returns the ODBC API return value.

  $r = $c -> sql_fetch_scroll ($sth, $SQL_FETCH_NEXT, $row++);

sql_foreign_keys (statement_handle, catalog_name, catalog_name_length, schema_name, schema_name_length, table_name, table_name_length, foreign_catalog_name, foreign_catalog_name_length, foreign_schema_name, foreign_schema_name_length, foreign_table_name, Iforeign_table_name_length>)

  Returns the ODBC API return value.

  $r = $c -> sql_foreign_keys ($sth, '', 0, '', 0, $table, length ($table),
                               '', 0, '', 0, $foreign_table, 
                               length ($foreign_table));

sql_free_connect (connection_handle)

  Returns the ODBC API return value.

  $r = $c -> sql_free_connect ($cnh);

sql_free_env (handle)

Convenience function to de-allocate an environment handle.

  $r = $c -> sql_free_env ($evh);

sql_free_handle (handle_type, handle)

  Returns the ODBC API return value.

  # Free environment handle

  $r = $c -> sql_free_handle ($SQL_HANDLE_ENV, $evh);

  # Free connection handle

  $r = $c -> sql_free_handle ($SQL_HANDLE_DBC, $cnh);

  # Free statement handle

  $r = $c -> sql_free_handle ($SQL_HANDLE_STMT, $sth);

sql_free_stmt (statement_handle, option)

  $r = $c -> sql_free_stmt ($sth, $SQL_CLOSE);

sql_get_connect_attr (connection_handle, attribute, maxlength)

sql_get_cursor_name (statement_handle, maxlength)

  Returns a list of 
  - API return value
  - Cursor name
  - Length of cursor name

  ($r, $cursorname, $length) = 
     $c -> sql_get_cursor_name ($sth, 255);

sql_get_data (statement_handle, column_number, data_type, maxlength)

  Returns a list of
  - API return value
  - Result text
  - Result text length

  ($r, $text, $len) = sql_get_data ($sth, 1, $SQL_C_CHAR, 255);

sql_get_diag_field (handle_type, handle, field_number, maxlength)

  Returns a list of
  - API return value
  - Server native error
  - ODBC error
  - ODBC error length

  ($r, $native, $text, $textlen) = 
     $c -> sql_get_diag_field ($SQL_HANDLE_STMT, $sth, 1, 255);

sql_get_diag_rec (handle_type, handle, record_number, maxlength)

  Returns a list of: 
  - API return value
  - SQL state
  - DBMS error number
  - Error text
  - Error text length

  If the return value is $SQL_NO_DATA, the remaining list elements
  are empty.

  ($r, $sqlstate, $native, $text, $textlen) = 
    $c -> sql_get_diag_rec ($SQL_HANDLE_ENV, $evh, 1, 255);

sql_get_env_attr (environment_handle, attribute, maxlength)

  Returns a list of: 
  - API return value
  - Attribute value
  - Attribute value length.

  If the return value is not $SQL_SUCCESS, the remaining list 
  elements are empty.

  ($result, $version, $versionlength) = 
    $c -> sql_get_env_attr ($evh, $SQL_ATTR_ODBC_VERSION, $maxlength)

sql_get_functions (connection_handle, function);

  Returns a list of 
  - API return value
  - Non-zero if function is supported, zero if not supported.

  my ($r, $s) = $c -> sql_get_functions ($cnh, $SQL_API_SQLALLOCHANDLESTD);

sql_get_info (connection_handle, attribute, maxlength);

  Returns a list of 
  - API return value
  - Attribute value
  - Attribute value length

  ($r, $dbmsname, $length) = 
     $c -> sql_get_info ($cnh, $SQL_SERVER_NAME, $maxlength)

sql_get_stmt_attr (statement_handle, attribute, maxlength)

  Returns a list of 
  - API return value
  - Attribute value
  - Attribute length

  my ($r, $text, $textlength) = 
    $c -> sql_get_stmt_attr ($sth, $SQL_ATTR_CURSOR_SCROLLABLE, 255);

sql_get_type_info (statement_handle, type)

Returns the ODBC API return value. The result of the query is a result set of the requested types.

  $r = $c -> sql_get_type_info ($sth, $SQL_ALL_TYPES);

sql_more_results (statement_handle)

  Returns the ODBC API return value.

  $r = $c -> sql_more_results ($sth);

sql_native_sql (connection_handle, query, query_length, maxlength)

  Returns a list of 
  - API return value
  - Translated SQL query
  - Length of translated query

  ($r, $nativequery, $length) = 
    $c -> sql_native_sql ($cnh, $query, length ($query), 255);

sql_num_result_columns (statment_handle)

  Returns a list of 
  - API return value
  - Number of columns in result set

  ($r, $ncols) = sql_num_result_columns ($sth);

sql_prepare (statment_handle, query, query_length)

  Returns the ODBC API value.

  $r = $c -> sql_prepare ($sth, $query, length ($query) );

sql_primary_keys (statement_handle, catalog_name, catalog_name_length, schema_name, schema_name_length, table_name, table_name_length)

  Return a result set of primary keys.  The table name is required.

sql_procedure_columns (statement_handle, catalog_name, catalog_name_length, schema_name, schema_name_length, procedure_name, procedure_name_length, column_name, column_name_length);

  Returns the ODBC API return value.

  $r = $c -> sql_procedure_columns ($sth, '', 0, '', 0, '', 0, '', 0);

sql_procedures (statement_handle, catalog_name, catalog_name_length, schema_name, schema_name_length, procedure_name, procedure_name_length);

  Returns the ODBC API return value.

  $r = &UnixODBC::SQLProcedures ($sth, '', 0, '', 0, '', 0);

sql_row_count (statement_handle)

  Returns a list of
  - API return value
  - Number of rows in result set

  ($r, $nrows) = sql_row_count ($sth);

sql_set_connect_attr (connection_handle, attribute, buffer, bufferlength)

  Deprecated in the ODBC standard.

sql_set_connect_option (connection_handle, option, value)

  # Write function call info to /tmp/sql.log.  

  $r = $c -> sql_set_connect_option ($cnh, $SQL_OPT_TRACE, 
                                     $SQL_OPT_TRACE_ON);

sql_set_cursor_name (statement_handle, cursorname, cursor_name_length)

  Returns the ODBC API return value.

  $r = $c -> sql_set_cursor_name ($sth, 'cursor', length('cursor'));

sql_set_env_attr (environment_handle, attribute, value, length_of_value_string)

  Returns the ODBC function return value.

  $r = sql_set_env_attr ($evh, $SQL_ATTR_ODBC_VERSION, $SQL_OV_ODBC2, 0);

sql_set_pos (statement_handle, row, orientation, lock)

  Returns the ODBC API return value.

  $r = $c -> sql_set_pos ($sth, 1, $SQL_POSITION, $SQL_LOCK_NO_CHANGE);

sql_set_scroll_options (statement_handle, concurrency, keyset, rowset)

Deprecated in ODBC 3.0.

sql_set_stmt_attr (statement_handle, attribute, value, length)

sql_special_columns (statement_handle, id_type, catalog_name, catalog_name_length, schema_name, schema_name_length, table_name, table_name_length, scope, nullable)

  Returns the ODBC API return value.

  $r = sql_special_columns ($sth, $SQL_ROWVER, '', 0, '', 0, 'titles', 6,
                            $SQL_SCOPE_CURROW, 0);

sql_statistics (statement_handle, catalog_name, catalog_name_length, schema_name, schema_name_length, table_name, table_name_length, unique, reserved)

  Returns the ODBC API return value.

  $r = $c -> sql_statistics ($sth, '', 0, '', 0, '', 0, 1, 1);

sql_table_privileges (statement_handle, catalog_name, catalog_name_length, schema_name, schema_name_length, table_name, table_name_length)

  Returns the ODBC API return value.

  $r = $c -> sql_table_privileges ($sth, '', 0, '', 0, '', 0);
    

sql_tables (statement_handle, catalog_name, catalog_name_length, schema_name, schema_name_length, table_name, table_name_length, table_type_name, table_type_name_length)

  Returns SQL API return value.  ODBC Level 3 drivers can specify
  wildcards.  Calls to sql_fetch and sql_get_data return a result
  set of:

  - Catalog name
  - Schema name
  - Table name
  - Table type
  - Remarks

  # Print the names of all tables of a DSN
  $r = sql_tables ($sth, '', 0, '', 0, '', 0, '' 0);
  while (1) {
     r = $c -> sql_fetch ($sth);
     last if $r == $SQL_NO_DATA;
     ($r, $text, $textlen) = 
       $c -> sql_get_data ($sth, 3, $SQL_C_CHAR, 255);
     if ($r != $SQL_SUCCESS) {
       ($r, $sqlstate, $native, $text, $textlen) = 
         $c -> sql_get_diag_rec ($SQL_HANDLE_STMT, $sth, 1, 255);
       print "Error: [sql_get_data]$text\n";
     } 
     print "$text\n";
  }

VERSION INFORMATION AND CREDITS

UnixODBC::BridgeServer.pm is part of the UnixODBC package.

Version: 0.25

Written by: Robert Allan Kiesling, rkies@cpan.org.

SEE ALSO

perl(1), UnixODBC(3), tkdm(1), odbcbridge(1), remotedsn(1), remotetables(1), RPC::PlServer(3), RPC::PlClient(3).