ODBC para Servidor de Bases de Datos PostGreSQL ( I )

Autor: Juan Antonio Martinez Castaño
E-mail: jantonio@drake.dit.upm.es


Indice:

  1. Presentación
  2. Introducción
  3. Instalación de PostGreSQL
  4. Un primer paseo por el API ODBC
  5. El API ODBC en Linux
  6. Conclusiones
  7. Referencias

Presentación

Una vez demostrado que como servidor de ficheros Linux no tiene rival, y que como servidor de InterNet no tiene nada que envidiar a los grandes sistemas, hoy vamos a tratar un otro apartado en el que linux se desenvuelve sin problemas: el de los servidores de bases de datos para redes de PC's


Introducción

Los usuarios de MS-Windows en entornos ofimáticos se encuentran con frecuencia con el problema del acceso remoto a bases de datos. Efectivamente MS-Dos y Windows nunca fueron pensados como sistemas de red. Incluso, cuando no hubo mas remedio, las soluciones no dejaron de ser sino un parche... Del mismo modo las bases de datos eran locales, con soluciones propietarias.

Por otro lado, los grandes sistemas llevan trabajando desde hace años con servidores de bases de datos. Accesos concurrentes, transacciones, bloqueos, rollback, etc, son procesos largamente conocidos y estudiados. El acceso de la informatica personal a las redes locales trajo al mundo ofimático los mismos problemas a los que los grandes mainframes se habían enfrentado hacia años. Solo había un problema: El sistema operativo. En efecto: todas las aplicaciones desarrolladas partíian de la base de un sistema operativo monotarea monousuario, sin servicios de red, y casi sin ningún tipo de control de acceso a los recursos. Incluso en la actualidad, Windows 95 tiene problemas con el accesso a recursos entre aplicaciones ( o si no, probad a abrir un documento con Word97 y -sin cerrar el documento- abriendo una ventana de MS-Dos intentad hacer alguna operación con dicho documento. !!Haced primero un backup!! )

Los primeros intentos de acceso concurrente a bases de datos desde PC's se realizan mediante recursos de compartición de archivos. Se utilizan los controles de acceso de NetBIOS para salvaguardar la consistencia de datos... falta todavía un paso: el convertir los programas de gestión de bases de datos a una arquitectura cliente-servidor, donde un proceso maestro es el que controla cada petición de acceso a la base de datos, y nuestro dBase, Paradox o Access no son sino user-interfaces de visualizacion de datos.

Tenemos pues diferentes enfoques, en función de la separación entre la aplicación y los ficheros de datos y de la relación que se establece entre ellos:

¿Cómo se establecen estos vínculos? En los grandes sistemas, y en las redes UNIX, desde el primer momento los clientes son aplicaciones independientes del servidor, hablan su lenguaje y se entienden de tú a tú con él. En sistemas basados en MS-Dos ( ej. Windows ) se hace necesario el proveer un interfaz entre la aplicación y los servidores. Del mismo modo, en los sistemas UNIX todo el mundo habla el mismo lenguaje de bases de datos -SQL-, mientras que los PC's están plagados de soluciones propietarias, en función de la aplicación y del fabricante. Se hace pues necesaria una arquitectura en capas para realizar las siguientes tareas: Para conseguir esta funcionalidad Microsoft definió en su día un API denominado Open DataBase Conectivity ( ODBC ). Toda aplicación de bases de datos que se precie para el mundo Windows debe ser capaz de implementar y manejar el API de acceso a la base de datos

Microsoft ha hecho público el API de programación por lo que -en teoría- cualquiera puede escribir un driver ODBC, las aplicaciones de databases que hablen ODBC puedan comunicarse con un servidor, bien sea local, remoto, fichero, aplicación o incluso otro programa de bases de datos que se esté ejecutando en la misma máquina ( esta es la teoría. Microsoft, siguiendo su política habitual, tiene la mala costumbre de saltarse sus propios estándares, y algunas aplicaciones suyas manejan extensiones al ODBC propias y no documentadas... )

Rizando el rizo, y puesto que ODBC es un estandard "de facto", el cliente de la base de datos no tiene siquiera por que ser un sistema de Microsoft. De hecho, existe un proyecto de colaboración en la comunidad InterNet para proveer a los sistemas UNIX de un API de acceso ODBC unificado para sus bases de datos. Uno podría preguntarse cúal es el sentido de todo esto, pues SQL tiene ya un API definido, y todos los UNIX saben hablar en SQL, pero se entiende fácilmente si pensamos que si el API de acceso a la base de datos es el mismo en Windows y en UNIX, el trabajo de porting se reduce considerablemente. Es mucho mas fácil convencer a los desarrolladores de bases de datos en Windows para que porten a Linux sus aplicaciones si se les proporciona el mismo API de programación, de manera que solo tengan que teclear "make"

ODBC no es sino un API de conectividad entre aplicaciones de bases de datos cliente y servidor. Dicho API esta organizado en varias capas: de aplicacion, de sistema, y de acceso.

En resumen: ODBC no es sino un API de conectividad entre aplicaciones de bases de datos cliente y servidor. Dicho API esta organizado en varias capas: de aplicacion, de sistema, y de acceso.

Hemos dividido este tema en dos partes:

Todos los ejemplos, gráficos y listados de estos artículos han sido realizados con PostGreSQL 6.3.2 en una Sparc-SLC con RedHat 4.2 SparcLinux y un Pentium 166MMX con Linux RedHat 5.0 , Windows 95 OSR2 y Office 97, conectados en red. En el CD-Rom se incluyen los fuentes y paquetes instalables de las últimas releases oficiales de los programas que aquí se explican, existentes en el momento de escribir el articulo


Instalación de PostGreSQL-6.3.2 bajo Linux

En el número 2 de Linux Actual se describió la instalación de MySQL como servidor de bases de datos. En este artículo se describe la instalación de PostGreSQL 6.3.2, con lo que los lectores tendrán así ocasión de poder establecer criterios para seleccionar su servidor favorito.

Si utilizamos una distribución tipo RedHat tendremos los siguientes paquetes:

postgresql-6.3.2-3.i386.rpm Paquete básico
postgresql-devel-6.3.2-3.i386.rpm API de programación PostGreSQL
postgresql-clients-6.3.2-3.i386.rpm Clientes bajo Linux
postgresql-data-6.3.2-3.i386.rpm Templates para bases de datos
postgresql-jdbc-6.3.2-3.i386.rpm Interfaz con Java Database Conectivity (JDBC)
postgresql-perl-6.3.2-3.i386.rpm Interfaz con Perl
Para instalarlos, no tendremos más que montar el CDROM y ejecutar:
root@cochito:/mnt/cdrom# rpm -v -i ${path_to_rpms}/postgresql*i386.rpm

En el caso de que ya tengamos una versión pre-instalada, es recomendable hacer el upgrade a ésta, por lo que deberemos añadir la opción --upgrade a la línea de comandos

En el caso de que no dispongamos de las utilidades de paquetería rpm, procederemos a coger el paquete .tar.gz y compilarlo. Para ello procederemos de la siguiente forma:

  1. Creamos un usuario "postgres" bajo cuyo uid se ejecutará todo el software de gestión de la database. ! Bajo ningún concepto ejecutaremos nunca dicho software con permisos de root !. Asimismo creamos el directorio de spool donde se van a guardar las databases del sistema:
    [root@sparky /root]# grep postgres /etc/passwd /etc/group
    /etc/passwd:postgres:!:100:101:PostGreSQL Server:/var/lib/pgsql:/bin/bash
    /etc/group:postgres::101:
    [root@sparky /root]# ls -la /var/lib/pgsql  
    total 3
    drwxr-xr-x   2 postgres postgres     1024 May 23 20:40 .
    drwxr-xr-x   8 root     root         1024 May 23 20:13 ..
    -rw-r--r--   1 postgres postgres       18 May 23 20:40 .bash_history
    
  2. Como root descomprimimos el paquete en el directorio deseado. ( normalmente /usr/local/src ).
  3. En el caso de que ya tuviéramos una versión de PostGreSQL instalada anteriormente, deberemos hacer un backup de las bases de datos existentes en el sistema. Remitimos al lector a los ficheros "INSTALL" que acompañan al paquete
  4. Ejecutamos:
    [root@sparky /usr/local/src/postgresql-6.3.2/src]# ./configure 
    [root@sparky /usr/local/src/postgresql-6.3.2/src]# make
    
  5. Es posible que deseemos modificar alguno de los parámetros de compilacion El comando "configure --help" y la documentación nos indican las diversas opciones. Especial mención merecen las opciones "--template", "--php", y "--perl". Consultar el fichero INSTALL para escoger los parámetros adecuados.
  6. El programa debería compilar sin problemas. Una vez finalizada la compilación "make install" nos instalará PostGreSQL en los directorios escogidos.
    En el caso de que no hayamos desactivado expresamente su generacisóon, se habrá creado la librería libpq.so.x.x . Deberemos añadir en el fichero /etc/ld.so.conf el path donde la hayamos instalado, y acto seguido ejecutaremos ldconfig para actualizar el cache del cargador de librerías dinámicas
  7. En los ficheros /etc/profile.d/postgresql.sh y /etc/profile.d/postgresql.csh instalamos los paths y las variables de entorno apropiadas:
    [root@sparky /root]# cat /etc/profile.d/postgresql.sh
    PATH=$PATH:/usr/local/pgsql/bin
    MANPATH=$MANPATH:/usr/local/pgsql/man
    PGLIB=/usr/local/pgsql/lib
    PGDATA=/var/lib/pgsql/data
    export PATH MANPATH PGLIB PGDATA
    
    [root@sparky /root]# cat /etc/profile.d/postgresql.csh
    setenv PATH $PATH:/usr/local/pgsql/bin
    setenv MANPATH $MANPATH:/usr/local/pgsql/man
    setenv PGLIB /usr/local/pgsql/lib
    setenv PGDATA /var/lib/pgsql/data
    
  8. Creamos los "esqueletos" de la database. Para ello hacemos "su - postgres" y ejecutamos "initdb"
  9. configuramos adecuadamente los ficheros de control de PostGreSQL, especialmente el fichero de control de accesos pg_hba.conf . De nuevo, nos remitimos al manual..
  10. El manual recomienda, antes de empezar a trabajar, ejecutar los programas de testing. Para ello deberemos arrancar el servidor en modo test, y ejecutar make en el directorio de testing. ( Leer fichero INSTALL )
  11. Finalmente, creamos el fichero /etc/rc.d/init.d/postgresql y configuramos con el "runlevel editor" el arranque en power-on del servidor de la base de datos. El listado 1 nos muestra un ejemplo de script de arranque para RedHat-5.0:

    #! /bin/sh
    # chkconfig: 345 85 15
    # description:  Starts and stops the PostgreSQL 
    #		backend daemon that handles
    #               all database requests.
    
    # Source function library.
    . /etc/rc.d/init.d/functions
    
    # Get config.
    . /etc/sysconfig/network
    
    # Check that networking is up.
    # Pretty much need it for postmaster.
    [ ${NETWORKING} = "no" ] && exit 0
    
    [ -f /usr/bin/postmaster ] || exit 0
    
    # See how we were called.
    case "$1" in
      start)
            echo -n "Starting postgresql service: "
            su postgres -c \
    		'/usr/bin/postmaster -S -i -D/var/lib/pgsql'
            sleep 1
            pid=`pidof postmaster`
            echo -n "postmaster [$pid]"
            touch /var/lock/subsys/postmaster
            echo
            ;;
      stop)
            echo -n "Stopping postgresql service: "
            killproc postmaster
            sleep 2
            rm -f /var/lock/subsys/postmaster
            echo
            ;;
      status)
            status postmaster
            ;;
      restart)
            $0 stop
            $0 start
            ;;
      *)
            echo "Usage: postgres.init {start|stop|status|restart}"
            exit 1
    esac
    
    exit 0
    
    Listado 1: fichero de arranque en power-on de PostGreSQL

  12. Arrancamos el sistema con "/etc/rc.d/init.d/postgresql start"
  13. Como usuario "postgres" vamos a crear una cuenta de acceso para i poder trabajar con el servidor de base de datos. Estas cuentas son exclusivas de la base de datos, y no hacen referencia a usuarios reales del sistema, aunque es bastante común tener una cuenta generica "sqluser" sin login, para uso exclusivo de PostGreSQL. Esto lo haremos con el comando
    [postgres@sparky:/var/lib/pgsql]$ createuser sqluser
    
    El programa createuser nos irá preguntando por los diversos privilegios de dicho usuario, su uid ( que -de nuevo-, no tiene por qué coincidir con el de un usuario real, aunque así sea en nuestro ejemplo ). Los diversos ficheros de configuración, indicarán qué usuarios tienen permiso para hacer qué cosas. De nuevo, para una descripción detallada, nos remitimos al manual
    En el caso de que nuestra base de datos vaya a ser utilizada desde el servidor de Web, mediante PHP, deberemos añadir un nuevo usuario "nobody", con el mismo userid y groupid que el usuario real. Recordemos que el servidor Apache se ejecuta como dicho usuario
  14. Si estabamos realizando un upgrade, éste es el momento de hacer un restore de las diversas databases que tuviéramos procedentes de una release anterior
  15. Creamos una base de datos para "jugar". El sistema trae ya una database generica "template1" pero ya se sabe que Murphy anda suelto, y no esta de más un poco de precaución. La denominaremos "odbctest"
    [postgres@sparky:/var/lib/pgsql]$ createdb odbctest
    
    El Concepto de base de datos relacional va más alla de la simple tabla: una RDB engloba tablas, indices, operadores, funciones, etc, bajo un nombre común, definiendo las interrelaciones entre los diversos elementos de dicha base de datos
    El concepto de base de datos en PostGreSQL, y en general en todas las bases de datos relacionales es mucho mas amplio que el tradicional de conjunto de registros, cada uno con "n" campos de diversos tipos. Aquí por database se entiende una agrupación de objetos, tales como tablas, indices, funciones operadores, etc, bajo un nombre común
    Ahora, dentro de la database "odbctest" vamos a crear una tabla con la que trabajar. Por el momento vamos a obviar la sintaxis SQL, dejandola para un articulo posterior, y vamos a introducir ciegamente los datos. Al final del articulo se indican referencias sobre manuales de SQL, ( si los lectores lo estiman oportuno, incluiremos en Linux Actual una serie sobre dicho lenguaje ). Simplemente indicar que PostGreSQL se acompaña de un interfaz de entrada directa de comandos SQL, denominado psql, que utilizaremos para introducir los datos en la database. El listado 2 muestra los datos que introduciremos en la database:

    create table telefonos (
    	nombre	char(25),
    	direccion char(40),
    	telefono  int
    );
    
    insert into telefonos 
        values ( 'E.T.S.I.Teleco','C. Universitaria s/n',5495700 );
    insert into telefonos 
        values ( 'Linux Actual','Alfonso Gomez 42',3040622 );
    insert into telefonos 
        values ( 'Juan Antonio','Mi Casa',12345678 );
    insert into telefonos 
        values ( 'Emergencias','Comunidad de Madrid',112 );
    
    Listado 2: programa de ejemplo de creacion de base de datos

    Para aquellos que no quieran introducir a mano los comandos, se incluye dicho listado en el CDROM, de manera, que en lugar de teclearlo, se puede cargar directamente desde psql con la secuencia de escape \i (include file)

    [postgres@sparky:/var/lib/pgsql]$ psql odbctest
    Welcome to the POSTGRESQL interactive sql monitor:
      Please read the file COPYRIGHT for copyright terms of POSTGRESQL
      
      type \? for help on slash commands
      type \q to quit
      type \g or terminate with semicolon to execute query
    You are currently connected to the database: odbctest
    
    odbctest=> \i /path/to/cdrom/sample/sql/include/file/telefonos.sql
    create table telefonos (
            nombre  char(25),
            direccion char(40),
            telefono  int
    );
    CREATE
    
    insert into telefonos
            values ( 'E.T.S.I.Teleco','C. Universitaria s/n',5495700 );
    INSERT 17584 1
    insert into telefonos
            values ( 'Linux Actual','Alfonso Gomez 42',3040622 );
    INSERT 17585 1
    insert into telefonos
            values ( 'Juan Antonio','Mi Casa',12345678 );
    INSERT 17586 1
    insert into telefonos
            values ( 'Emergencias','Comunidad de Madrid',112 );
    INSERT 17587 1
    
    EOF
    odbctest=> select nombre,direccion from telefonos 
    	where telefono=5495700;
    nombre                   |direccion                               
    -------------------------+----------------------------------------
    E.T.S.I.Teleco           |Ciudad Universitaria s/n                
    (1 row)
    odbctest=> \q
    [postgres@sparky:/var/lib/pgsql]$
    
  16. Ya tenemos nuestro servidor de databases instalado y funcionando, y hemos creado una pequeña base de datos para empezar a trabajar. A continuación se describirá cómo instalar las librerías ODBC y el driver ODBC para PostGreSQL en Linux, haciendo previamente una breve introducción al funcionamiento del API ODBC.


Un primer paseo por el API de ODBC

Antes de emprender la instalación de ODBC es preciso aclarar algunos conceptos de funcionamiento del API de ODBC.

Como hemos explicado en la introdución, ODBC es un API de interfaz entre clientes de bases de datos y servidores de bases de datos. La figura 1 ilustra este esquema:

Estructura del API ODBC
figura 1: Estructura en capas del API ODBC

La primera capa constituye la librería del API que utilizan las diversas aplicaciones que "hablan" ODBC. Microsoft proporciona para sus sistemas el fichero ODBC32.DLL, que contienen el API y el interfaz con el sistema operativo, permitiendo a los desarrolladores de controladores ODBC incluír dicha librería en sus distribuciones ( de la misma manera que para la DLL de controles Visual Basic VBRUN.DLL ). Para sistemas UNIX, el proyecto FreeODBC, ha desarrollado su propia librería GPL libodbc.so.x.x que es totalmente compatible con las especificaciones descritas por Microsoft

El administrador de orígenes de datos es el responsable del "rutado" de peticiones de ODBC desde la librería hasta los controladores. Para ello se discriminan tres tipos de orígenes de datos: de usuario, de archivo y de sistema. Esta nomenclatura es motivo frecuente de confusión: cuando desde Windows se abre desde el panel de control el menú de "controladores ODBC" se encuentra con esta clasificación, y cuando abre cada una de las ventanas se encuentra con los mismos contenidos... Vamos a explicarlo un poco:

Por último, cada origen de datos tiene asociado un controlador, que actúa de "pasarela" entre el API y el acceso físico a los datos


El API de ODBC en Linux

Llegados a este punto preguntamos: ¿Cómo funciona de cara al programador la librería ODBC?. La respuesta es ridículamente sencilla: el API ODBC consiste en un interfaz que implementa un método de pasar peticiones en lenguaje SQL a través de una serie de funciones. Con ODBC podemos:

En la práctica, ni todas las aplicaciones, ni todos los controladores de orígenes de datos son capaces de gestionar todas las funcionalidades previstas por el API. Por ello se establecen los denominados "niveles de conformidad SQL" en la aplicación así como "niveles de conformidad del controlador", que permiten al administrador de orígenes de datos saber qué puede hacer tanto con el driver como con la aplicación.

Remitimos al lector a la literatura indicada en las referencias para buscar las especificaciones y descripciones de cada nivel de compatibilidad

El proyecto FreeODBC ha desarrollado una librería, denominada iODBC, que cumple con las especificaciones del API ODBC 2.0 de Microsoft, y que integra las funciones de API y de administrador de orígenes de datos.
¿Cómo se aplica ésto en sistemas UNIX? El proyecto FreeODBC ha desarrollado una librería, denominada iODBC, que cumple con las especificaciones del API ODBC 2.0 de Microsoft, y que integra las funciones de API y de administrador de orígenes de datos. Cada servidor de bases de datos provee un driver que hace las funciones de controlador de orígenes de datos y de origen de datos de sistema específico de cada servidor de bases de datos.
Existe un fichero ${HOME}/.iodbc.ini, que indica a la librería libodbc.so.x.x, los controladores de que dispone cada sistema, y cómo se accede a ellos. Todo el interfaz esta implementado mediante librerías dinámicas. El resultado de todo esto, es que el programador se encuentra con un API virtualmente idéntico al que se encontraría si estuviera trabajando en una maquina M$-Windows

En el CD-Rom que se acompaña a esta revista, bajo el directorio odbc/iodbc encontramos los siguientes ficheros:

Buceando por las paginas web, podremos encontrar drivers de iODBC para casi todas las bases de datos disponibles en Linux. De hecho, Los desarrolladores de iODBC han decidido incluír en sus nuevas releases todos los drivers de aquellas bases de datos que libremente los provean, incluyendo además de serie la pasarela JDBC-ODBC.


Conclusión

En este primer artículo dedicado a la conectividad ODBC, se han introducido los conceptos básicos de dicho sistema. Asimismo hemos aprendido a instalar y configurar Uno de los servidores de bases de datos más conocidos: PostGreSQL, así como los drivers y librerías ODBC para UNIX.

En el próximo número de Linux Actual, profundizaremos en el API de ODBC, dando algunos ejemplos de programación, y se explicará la forma en que debemos instalar los drivers ODBC para PostGreSQL en sistemas Microsoft Windows-3.XX y Windows-95, con ejemplos de utilización desde MS-Access-97.


Referencias