Art�culo para la revista Linux Actual n�mero 15:

Javier Fern�ndez-Sanguino Pe�a jfs@computer.org

24 julio 2000


En �sta entrega del desarrollo de bases de datos en Internet con GNU/Linux se van a ver los aspectos espec�ficos del desarrollo de la aplicaci�n que ya se describi� en los anteriores.

1. Introducci�n

Como ya se introdujo en el n�mero anterior, la aplicaci�n concreta que se va a abordar es la creaci�n de una Asociaci�n de Antiguos Alumnos en Internet, para que sea posible, a dichas personas, acceder a trav�s de un cliente universal (un navegador de WWW) a una base de datos con la informaci�n relativa a los dem�s antiguos alumnos.

De esta forma esta base de datos puede servir para que los distintos exalumnos puedan comunicarse entre s�, saber d�nde se encuentra trabajando cada uno y as� estrechar los lazos que ya en su d�a se generaron en el Instituto, Escuela o Universidad donde se conocieron.

La aplicaci�n en concreto se dividir� en:

En este art�culo se van a ver todos estos aspectos de la aplicaci�n, acompa��ndolos del listado de c�digo necesario para llevarlos a cabo. Como ya se introdujo en los anteriores art�culos, para implementar esta aplicaci�n se va a utilizar WWW-SQL (en su versi�n para PostgreSQL).

******************** FIGURA 1 *************************

2. WWW-SQL

Ya se vio en el art�culo anterior una breve introducci�n al lenguaje de programaci�n de scripts WWW-SQL en comparaci�n con otras t�cnicas para programar el acceso a servidores de web desde p�ginas HTML. Aqu� se har� m�s hincapi� en la estructura del lenguaje y en sus posibilidades.

WWW-SQL es un programa CGI dise�ado para crear p�ginas de web desde bases de datos PostgreSQL o MySQL, implementado por James Henstridge. El programa viene acompa�ado de un completo manual con algunos ejemplos, pero aqu� se resumen algunas de sus capacidades.

La funci�n de WWW-SQL es procesar una p�gina HTML e interpretar determinadas �rdenes contenidas en �sta, calcular los resultados de ejecuci�n de estas �rdenes y devolver la p�gina modificada. Como el lector puede adivinar, las �rdenes que va a ofrecer el lenguaje van a estar, fundamentalmente, relacionadas con el acceso a bases de datos.

La sintaxis de las marcas reconocidas por WWW-SQL es la siguiente:

<! SQL orden argumento1 argumento2 ... >

La orden es cualesquiera de los comandos reconocidos por el lenguaje, mientras que argumento1 y argumento2 (aunque puede haber m�s argumentos) son los datos que se le dan a dicho comando para variar su comportamiento.

Algunas de los comandos m�s importantes en WWW-SQL son:

Adem�s, el lenguaje tiene soporte para dos tipos de estructuras de control (if.. then...elseif..endif, y while..done), posibilidad de gestionar las variables recibidas a trav�s del CGI script (rellenadas, por ejemplo, desde un formulario), capacidad de gestionar Cookies y algunas estructuras ya implementadas para poder gestionar f�cilmente tablas y algunos elementos de formularios (como listas desplegables).

La estructura normal de una p�gina con SQL embebido con este lenguaje tendr�, t�picamente, esta estructura:

<!-- Cabeceras HTML -->
<!sql connect>
<!sql database dbname>
<!-- c�digo HTML y �rdenes www-sql -->
<!sql close>
<!-- Pie HTML -->

Un programador experimentado podr� echar en falta muchas capacidades como: estructuras de control m�s potentes, la posibilidad de modularizar el c�digo a trav�s de funciones, etc.. pero WWW-SQL es en realidad la alternativa menos compleja para abordar el desarrollo de los sistemas que aqu� se est�n tratando. Si uno desea un lenguaje m�s expresivo puede probar con PHP/FI o con PERL embebido.

En cualquier caso, WWW-SQL es la alternativa m�s interesante cuando se quiere hacer el desarrollo de un prototipo, lo que se llama com�nmente "prueba de concepto".

3. Desarrollo del servidor.

El esquema general del servidor se muestra en la figura 2. Como se puede ver en �sta el servidor se va a dividir, fundamentalmente en dos partes, una parte de contenidos p�blicos, en los que no se va a restringir el acceso al usuario y una parte de contenidos privados en los que se va a solicitar una autenticaci�n previa.

Por otro lado, es necesario tener alguna forma de que los usuarios nuevos del servidor introduzcan sus datos para darse de alta por primera vez.

***************** FIGURA 2 ***************************

Adem�s, en este tipo de sistemas en los que se va a almacenar informaci�n personal, ser� necesario cuidarse de que los usuarios que se dan de alta son reales. �sta ser�a la funci�n de un "certificador" (o notario), que diera fe de que los datos introducidos corresponden a una persona real y que puede pertenecer por pleno derecho a la asociaci�n. �sta figura y la forma de introducirla no se va a ver en este art�culo pues se sale del esquema propuesto de desarrollo. En cualquier caso en esta serie se pretende hacer una exposici�n del problema t�cnico existente no del problema tambi�n en sus aspectos sociol�gicos (pero que en cualquier caso no se deben olvidar).

Evidentemente, para que el servidor tenga una cierta uniformidad en cuanto a aspecto, las p�ginas tendr�n que facilitar al desarrollador que "obvie" los aspectos correspondientes a la parte est�tica y se pueda centrar en el desarrollo de la aplicaci�n. Esto puede hacerse f�cilmente haciendo uso de WML (Website Meta Language), este tema es muy interesante pero se sale del �mbito de este art�culo.

Como el lector puede suponer, la parte del desarrollo del servidor en la que se va a hacer hincapi� es la parte de la programaci�n en el interfaz del acceso a la base de datos, as� como la parte de autentificaci�n. Se va a empezar con la entrada de nuevos usuarios, es decir el alta de los mismos, y se podr�n empezar a ver algunas de las potencias (y debilidades) de WWW-SQL.

3.1 Alta de usuarios.

El alta de usuarios se har�, como es habitual a trav�s de un formulario de entrada HTML en el que el usuario rellenar� los datos y enviar� �stos al servidor al pulsar el bot�n de "Env�o".

La funci�n del servidor una vez llevada a cabo esta tarea ser�a:

El �ltimo paso es necesario para que se haga la entrada de los datos en dos partes. Como ya se vio en el esquema entidad relaci�n, en principio todos los usuarios registrados tienen que tener un conjunto de datos, pero hay otros, como tel�fono o direcci�n de correo electr�nico, que no tienen por qu� estar presentes y finalmente, una tabla (la de empresas y trabajadores en ella) en la que s�lo se han de introducir datos si el usuario est� trabajando.

Gracias a esto el alta de los usuarios es sencilla, como se muestra en el listado 1. Si el usuario ha introducido el DNI, elemento que se considera imprescindible, se insertar�n los datos dados en la base de datos. Si adem�s se han introducido otra serie de datos (como son el n�mero de tel�fono y la direcci�n de correo) se introducir�n estos en las tablas correspondientes. Finalmente, si el usuario ha indicado que est� trabajando se le dirigir� a la segunda parte de la entrada de datos.

*************** LISTADO 1 ***********************

Como se ve la entrada de los datos b�sicos no tienen gran complicaci�n, se podr�a hacer m�s compleja a�adiendo comprobaciones de tipos de datos antes de introducirlos, pero otras funciones, como la detecci�n de problemas de inserci�n no pueden "interceptarse" en WWW-SQL. Es aqu� donde vemos los primeros problemas y debilidades de �ste. Todo funciona bien si los datos de entrada son correctos y no se encuentra con casos "extra�os". Pero si se da cualquier problema, el error se le mostrar� directamente al usuario en la p�gina HTML devuelta, ya que no es posible "interceptarlo". En cualquier caso esta implementaci�n nos sirve como prototipo. Este tipo de errores s�lo se pueden mejorar si se reimplementa el interfaz en un lenguaje m�s vers�til que soporte m�s posibilidades.

La entrada de datos de empresas resulta algo m�s compleja. Cuando un usuario se da de alta como trabajador y quiere indicar la empresa en la que est� trabajando y su puesto, pueden darse dos casos, el caso de que la empresa no exista ya en la base de datos y sea el usuario el encargado de introducir los datos de �sta, o el caso de que la empresa ya exista y el usuario pueda sencillamente seleccionarla.

El interfaz que permite dar de alta estos datos tiene que contemplar ambos casos. Se puede considerar que es el usuario el que tiene que introducir siempre los datos de la empresa en la que trabaja. Pero entonces no podr� "ver" las empresas que ya est�n en la base de datos, y se dar� el caso de que existan m�ltiples personas que trabajan en la misma empresa pero que no sea "la misma" a efectos de la base de datos. Si sucede esto se est� duplicando de forma innecesaria informaci�n. Tambi�n puede suceder que s�lo se le deje al usuario seleccionar una empresa de las ya existentes, con lo que se limita la versatilidad del interfaz dado que tiene solicitar a alguien (quiz�s al administrador) que d� de alta nuevas empresas para que pueda �l indicar en el interfaz que est� trabajando en ella.

Por ello la opci�n elegida es la mostrada en el listado 2, en el que la diferencia fundamental con respecto al formulario de entrada de datos personales, es que parte del formulario se construye en base a la informaci�n de la base de datos.

As�, por un lado el usuario introduce siempre informaci�n de su cargo y departamento. Tiene que haber dos opciones:

************** LISTADO 2 *************************

Tras esto, como se muestra en el listado 3, se proceder� a enviar los datos a un programa encargado de tratarlos. Si el usuario ha introducido una nueva empresa, �sta ser� introducida junto con sus datos en la tabla correspondiente. Y, en cualquier caso, se introducir� la informaci�n relativa del puesto y cargo que desempe�a la persona dentro de la empresa en la tabla que identifica las relaciones laborales entre personas y empresas.

***************** LISTADO 3 **************************

Una mejora a estos formularios ser�a ofrecer la posibilidad de realizar entre la lista de las empresas, por ejemplo, b�squedas de cadenas o ser capaz de comprobar que una empresa que se va a introducir se parece "sospechosamente" a otra ya introducida (por ejemplo, porque sea el mismo nombre pero sin acentos). Pero en principio el prototipo es suficientemente funcional. En realidad se puedan hacer muchas mejoras para que luego, en el uso diario, se evite que los usuarios introduzcan empresas distintas que luego, realmente, son la misma.

3.2 Autenticaci�n.

Para lograr limitar el acceso a la informaci�n contenida en la base de datos, con el fin de mantener el prop�sito de la asociaci�n, es necesario que los usuarios sean autenticados antes de acceder a la parte privada del servidor. No interesa que cualquiera pueda acceder a los datos generados de todos los miembros.

�C�mo se puede saber si qui�n accede tiene derecho, o no, de consultar los datos? Muy sencillo, s�lo aquel que ya ha sido registrado puede hacerlo por lo que se necesita realizar alg�n tipo de pregunta con la que se puede saber que la persona que est� accediendo ha sido registrado previamente. Para hacer la pregunta se puede escoger parte de la informaci�n utilizada en el registro, pero ha de ser de tal manera que el que accede, al darla, est� demostrando de forma fehaciente su identidad.

�sta no es la �nica posibilidad para solventar este tipo de situaci�n. Habitualmente, en los servidores con alg�n tipo de autenticaci�n de usuarios, se le da la posibilidad a �stos para elegir un nombre de usuario y una clave que se introducen al registrarse. El problema surge, sin embargo, cuando pasa mucho tiempo desde que el usuario se registr� y vuelve a acceder. D�ndose el caso, frecuente, de que se haya olvidado la contrase�a elegida y se tiene que solicitar su env�o. Por las condiciones del servicio que se va a implementar es m�s que posible que se de �ste tipo de situaci�n, ya que en principio no tiene mucho sentido realizar consultas diarias.

Para evitar este problema en el dise�o planteado, se ha optado por preguntar al usuario informaci�n que s�lo �ste conoce y no vaya a olvidar con facilidad.

Si se estudia la informaci�n almacenada en la base de datos sobre cada persona, se puede ver que hay s�lo son algunos los campos que s�lo vaya a ser conocidos por el que acceder y no puedan estar sujetos a un ataque por "fuerza bruta" (probar todas las combinaciones posibles hasta encontrar una respuestas v�lida).

Sin embargo s� que se pueden escoger parejas de campos que sea m�s improbable que puedan ser conocidas al mismo tiempo. Por ello se ha elegido dentro del desarrollo que el usuario tenga que responder con dos datos que va a conocer siempre y no olvidar� f�cilmente y que, por otro lado, es dif�cil que otra persona pueda conseguir reunir.

Los datos escogidos han sido el DNI y la fecha de nacimiento. La funci�n del interfaz a la hora de autenticar ser�, por tanto, solicitar �stos al usuario y comprobar si son correctos. Esto es, si hay alg�n usuario en el que concuerden ambos valores, de forma que se podr� saber qui�n ha sido el usuario registrado. Evidentemente, ning�n sistema de autenticaci�n es perfecto y �ste, tambi�n, ser� susceptible de fallos.

En cualquier caso, queda a�n pendiente establecer alg�n mecanismo para que el servidor "sepa" que el usuario ha sido autenticado y no le pregunte esta informaci�n cada vez que quiera acceder al �rea privada.

Hay por lo menos dos mecanismos para hacer �stos, y los dos derivan de el hecho de que las transacciones a trav�s del protocolo HTTP carecen, en principio, del concepto de "estado":

Para facilitar el desarrollo se ha elegido �ste �ltimo ya que es un mecanismos que se integra muy bien con el esquema de base de datos propuesto. De esta forma se puede encargar la base de datos de guardar tambi�n la informaci�n relacionada con las sesiones si se desea.

Hay que destacar, sin embargo, que se podr�a llegar a utilizar autenticaci�n basada en el servidor si se utilizar un m�dulo de autenticaci�n que funcionara contra una base de datos relacional (SQL). Existe una implementaci�n de un m�dulo de este tipo que se ha dejado de distribuir con Apache, ya que s�lo ofrec�a la posibilidad de comunicarse con la base de datos Msql. Se est� trabajando, sin embargo, en una implementaci�n gen�rica (m�dulo mod_auth_sql) para poder utilizar cualquier base de datos en el primer caso.

Uso de cookies.

La forma de establecer el mecanismo de autenticaci�n en base a una "prueba" que entrega el cliente es haciendo uso del concepto de cookies.

Las cookies fueron una propuesta, inicialmente de Nestcape Communications, para ser capaz de gestionar transacciones con estado en el entorno WWW. El problema fundamental es que no se puede implementar aplicaciones del estilo de "carrito de la compra" porque en ning�n lado se pod�a, en principio, almacenar informaci�n de lo que ha hecho el usuario. Este tipo de sesiones deber�an soportar, adem�s, que el cliente se desconectara y volviera un tiempo m�s adelante y siguiera teniendo las mismas cosas seleccionadas "en el carrito". Este mecanismo se especifica con detalle en el est�ndar de Internet RFC 2109 del 27 de agosto de 1999.

Cada cliente puede guardar un n�mero ilimitado de cookies que no son m�s que pares de atributo-valor asignado a un dominio concreto y que el cliente almacena, pudiendo guardar m�s informaci�n como comentario, tiempo de vida, etc... El cliente, si tiene el soporte de cookies activado, puede recibir �stas y, posteriormente, deber� darlas cada vez que accede a un servidor dentro del dominio indicado.

Es evidente, sin embargo que existe la posibilidad de ataques a este sistema por parte de elementos que est�n "escuchando" la comunicaci�n entre cliente servidor. Si pueden recoger la cookie podr�an hacerse "pasar" por otro usuario. Para esto hay dos soluciones:

En cualquier caso, a�n a pesar de los problemas de autenticaci�n, en este prototipo se ha optado por utilizar un esquema m�s sencillo en el que el servidor va a entregar una cookie con un valor determinado (en este caso el DNI) y va a "confiar" en el cliente que tenga una cookie para el dominio donde est� ubicado el servidor de la base de datos con un contenido v�lido en este campo.

Como se puede ver en el listado 4, se hace una consulta a la base de datos con los valores dados en el formulario (dni y fecha) que son contrastados con la base de datos. Si existe un usuario con estos mismos datos se le entrega entonces una cookie a trav�s de la p�gina HTML (tag META: Set-Cookie y Set-Cookie2, se utilizan ambos por compatibilidad).

********************* LISTADO 4 *************************

Una vez hecho esto se puede incluir una comprobaci�n en cada p�gina. �sta se asegura de que el usuario ha sido autenticado utilizando el c�digo mostrado en el listado 5.

********************* LISTADO 5 ************************

3.3 Consultas

Finalmente, es necesario implementar herramientas para que los usuarios registrados puedan hacer uso de la informaci�n almacenada en la base de datos. En realidad aqu� hay muchas aplicaciones posibles, pero las que primero se pueden pensar son:

No se van a explicar en detalle todas estas consultas, ya que el hecho de implementarlas en general no es m�s que el realizar una consulta SQL y mostrar los datos en una tabla.

Por ello se va a mostrar s�lo la segunda consulta, el "list�n telef�nico" generado en base a los datos de la base de datos. Como se puede ver en el listado 6 se hace un select cruzando tres de las tablas de la base de datos para al final sacar un vector con la informaci�n personal (nombre y apellidos) y de contacto (n�mero de tel�fono y correo electr�nico) de la base de datos.

********************* LISTADO 6 ************************

Como se puede ver en el listado lo que se hace es recoger un n�mero limitado de resultados (definido en la variable step) de la consulta realizado y llamar a la funci�n print_rows para que todos estos se impriman en una tabla HTML. El programa, adem�s, es capaz de llamarse a s� mismo incrementando la cuenta (offset, variable ofs) para poder ir recuperando p�ginas sucesivas de informaci�n de la consulta y as� no tener que mostrar toda la consulta de golpe.

Como se puede ver en el listado 7 esta misma filosof�a de ense�ar los resultados de una consulta se puede aplicar a consultas cada vez m�s complicadas, como puede ser el caso de buscar qu� personas est�n trabajando en una empresa determinada.

****************** LISTADO 7 ******************************

4. Conclusiones

Con este art�culo se concluye la implementaci�n de un acceso a una base de datos a trav�s de un interfaz WWW habiendo visto todos los aspectos, al menos superficialmente (con las restricciones que pueda tener una publicaci�n como �sta), de dise�o y desarrollo, as� como las alternativas posibles de implementaci�n.

Este prototipo es, por supuesto, muy mejorable. Se han visto algunas de las deficiencias de www-psql para tratar situaciones complejas, como pod�a ser la entrada de datos. Este tipo de situaciones podr�a evitarse a�adiendo programaci�n a los interfaces tambi�n en Javascript, pero, en cualquier caso, siempre es necesario que el servidor compruebe que los datos recibidos son correctos (no se puede "fiar" de lo que le llega). Una alternativa m�s vers�til y que podr� enfrentarse mejor a este problema ser�a reimplementar el interfaz para utilizar PERL embedido o PHP/FI. Ambos van a permitir tener un acceso m�s transparente a la base de datos, al mismo tiempo que posibilitar�an la intercepci�n de errores y la comprobaci�n de los datos recibidos de una manera mucho m�s elegante.

En cualquier caso estos temas quedan pendientes para sucesivos art�culos. Baste decir que el desarrollo realizado del prototipo ha sido un desarrollo real, que se encuentra en fase de pruebas, para llevar a cabo este tipo de asociaci�n de antiguos alumnos en una Escuela de la Universidad Polit�cnica de Madrid. El c�digo del desarrollo est� a disposici�n de las personas interesadas, contacte con el autor si lo desea.

Tambi�n quedar�a pendiente la posibilidad de mejorar este servicio, lig�ndolo a una lista de correo. Esta lista puede servir de medio para comunicar a los distintos usuarios registrados. Puede ser util, por tanto, suscribir o desuscribirles en funci�n de altas y bajas de la base datos. Asismismo, ser�a posible enviar un resumen peri�dico de altas y bajas de forma autom�tica a dicha lista.

5. Sumarios

El servicio sirve como punto de encuentro.

WWW-SQL es un CGI que interpreta p�ginas web.

Un programador puede echar en falta estructuras complejas en WWW-SQL.

El servidor se divide en dos partes.

Se hace hincapi� en el acceso a la base de datos.

La entrada de datos se hace a trav�s de un formulario.

Se pueden implementar m�ltiples consultas �tiles.

Aqu� se completa la implementaci�n del prototipo.

Se puede mejorar utilizando ePERL o PHP/FI.

6. Listados

LISTADO 1-

<HTML>
<HEAD>
<TITLE>Alta de usuario</TITLE>
<! sql if "$dni" == "">
<! sql print "Error: Debe dar un DNI">
<! sql setexpr alta 0>
<! sql else>
<! sql connect localhost jfs>
<! sql database exalumnos>
<! sql query "begin">
<! sql query "insert into persona (dni, nombre_persona, apellidos_persona , calle_persona, ciudad_persona, pais_persona, codigo_postal, graduacion, ingreso, fecha_nacimiento) values ( $dni, '$nombre', '$apellidos','$calle', '$ciudad', '$pais', '$codigo_postal', $fecha_grad, $fecha_ingreso, '?fecha_nac')">
<! sql query "end">
<! sql print "<META http-equiv=\"Set-Cookie\" content=\"dni="$dni;" path=/\">" >
<! sql print "<META http-equiv=\"Set-Cookie2\" content=\"dni="$dni;" path=/\">" >
<! sql if "$email" != "">
<! sql query "begin">
<! sql query "insert into usa_mail (dni, e_mail) values ( $dni, '$email')">
<! sql query "end">
<! sql endif>
<! sql if "$telefono" != "">
<! sql query "begin">
<! sql query "insert into usa_tfo (dni, telefono, prefijo) values ( $dni, '$telefono', '$prefijo')">
<! sql query "end">
<! sql endif>
<! sql setexpr alta 1>
<! sql if "$trabajo" == "y">
<! sql print "<META http-equiv=\"refresh\" content=\"1;URL=alta_empresa.html\">" >
<! sql endif>
<BODY>
<! sql if $alta == 1>
<! sql print "Su solicitud ha sido aceptada.">
<! sql if "$trabajo" == "y">
<! sql print "<A HREF=\"alta_empresa.html\">D� de alta a su empresa</A>." >
<! sql endif>
<! sql close>
<! sql endif>
<! sql endif>
</BODY>
</HTML>

PIE LISTADO 1: C�digo para dar de alta a un usuario

LISTADO 2-

#use wml::exalumnos::plantilla title="D� de alta su empresa" minititle="Alta empresa"
<H1>D� de alta su empresa en la Base de Datos:</H1>
<BR>
<FORM METHOD="GET" ACTION="alta_empresa.pgsql">
Su puesto dentro de la empresa: <INPUT TYPE="TEXT" NAME="puesto"><BR>
Su departamento dentro de la empresa: <INPUT TYPE="TEXT" NAME="departamento"><BR>
<HR>

<protect>
<! sql connect localhost nobody >
<! sql database exalumnos >
<! sql query "begin" >
<! sql query "declare tmp cursor for select nombre_empresa from empresa" >
<! sql if $NUM_ROWS != 0 >
<! sql query "fetch all in tmp" q1 >
Busque su empresa: <SELECT NAME="empresa">
<OPTION VALUE="" DEFAULT>
<! sql print_rows q1 "<OPTION VALUE=\"@q1.0\">@q1.0">
</SELECT><BR>
<! sql endif >
<! sql free q1 >
<! sql query "end">
</protect>
<STRONG>S�lo si su empresa no est� en la lista previa introduzca los datos de �sta:</STRONG><BR>

Nombre de la empresa: <INPUT TYPE="TEXT" NAME="nombre"><BR>
Direcci�n:
Calle: <INPUT TYPE="TEXT" NAME="calle"><BR>
Ciudad: <INPUT TYPE="TEXT" NAME="ciudad"><BR>
Pa�s: <INPUT TYPE="TEXT" NAME="pais"><BR>
C�digo postal: <INPUT TYPE="TEXT" NAME="codigo_postal"><BR>
Actividad: <INPUT TYPE="TEXT" NAME="actividad"><BR>
N�mero aproximado de empleados: <INPUT TYPE="TEXT" NAME="empleados"><BR>

<INPUT TYPE="SUBMIT" VALUE="Dar de Alta">
</FORM>
</BODY>
</HTML>

PIE LISTADO 2: Formulario para darse de alta en una empresa

LISTADO 3-

#use wml::exalumnos::plantilla title="Alta de su empresa" autorizacion
# aqu� se usa la cookie que se ha puesto antes para poner el valor a
# trabaja_en empresa
<protect>
<! sql connect localhost  jfs >
<! sql database exalumnos >
<! sql query "begin" >
<! sql if $empresa = "" >
<! sql query "insert into empresa (nombre_empresa,
calle_empresa, ciudad_empresa, pais_empresa, codigo_postal,actividad, num_empleados)
values ( '$nombre', '$calle', '$ciudad', '$pais',
'$codigo_postal', '$actividad', $empleados )" >
<! sql else >
<! sql set nombre "$empresa" >
<! sql endif >
<! sql query "insert into trabaja_en (dni, nombre_empresa, puesto ,departamento)
values ( '$dni', '$nombre', '$puesto', '$departamento')" >
<! sql query "end" >
<! sql print "<H1>Solicitud aceptada</H1>">
<! sql print "<P>Se han registrados sus datos asi como los de la empresa en los que trabaja. "</P>>
<! sql print "<P>Gracias por darse de alta</P>.">
<! sql close>
</protect>

PIE LISTADO 3: Alta de una empresa

LISTADO 4-

<HTML>
<HEAD>
<TITLE>Acceso de usuario</TITLE>

<! sql setdefault dni 0 >
<! sql if $dni == 0 >
<! sql print "<META http-equiv=\"refresh\" content=\"1;URL=respuesta/rechazado.html\">" >
<! sql setexpr aceptado 0 >
<! sql else >
<! sql connect localhost nobody >
<! sql database exalumnos >
<! sql query "begin" >
<! sql query "declare tmp cursor for select * from persona where dni=$dni and fecha_nacimiento='?fecha'" >
<! sql query "fetch 10 in tmp" q1 >
<! sql query "end" >
<! sql free q1 >
<! sql if $NUM_ROWS != 0 >
<! sql print "<META http-equiv=\"refresh\"content=\"1;URL=respuesta/aceptado.html\">" >
<! sql print "<META http-equiv=\"Set-Cookie\" content=\"dni=$dni;path=/\">" >
<! sql print "<META http-equiv=\"Set-Cookie2\" content=\"dni=$dni;path=/\">" >
<! sql setexpr aceptado 1 >
<! sql else >
<! sql print "<META http-equiv=\"refresh\" content=\"1;URL=respuesta/rechazado.html\">" >
<! sql setexpr aceptado 0 >
<! sql close>
<! sql endif >
<! sql endif >

</HEAD>
<BODY>

<! sql if $aceptado == 0 >
<! sql print "Lo siento su petici�n ha sido <A HREF=\"respuesta/rechazado.html\">rechazada</A>." >
<! sql else >
<! sql print "Su petici�n ha sido <A HREF=\"respuesta/aceptado.html\">aceptada</A>." >
<! sql endif >

</BODY>
</HTML>

PIE LISTADO 4: Autenticaci�n de un usuario

LISTADO 5-

<! sql setdefault dni 0 >
<! sql if \$dni == 0 >
<H1>Error</H1>
<P>No conozco su DNI. Vaya a la <A HREF=\"$(USER)/alta.html\">p�gina de altas</A> si a�n no se ha dado de alta o a la <A HREF=\"$(USER)/acceso.html\">p�gina de acceso</A> si no ha sido autentificado por el servidor.</P>
<protect>
<! sql else >
</protect>

PIE LISTADO 5: Autenticaci�n del usuario en base a la cookie recibida.

LISTADO 6

#use wml::exalumnos::plantilla title="Listin de antiguos alumnos" autorizacion
<H1>List�n de antiguos alumnos</H1>
<protect>
<! sql connect localhost nobody >
<! sql database exalumnos >
<! sql setdefault ofs 0 >
<! sql setdefault step 10 >
<! sql query "begin" >
<! sql query "declare tmp cursor for select nombre_persona, apellidos_persona, telefono, e_mail  from persona, usa_tfo, usa_mail where persona.dni=usa_tfo.dni and persona.dni=usa_mail.dni order by apellidos_persona" >
<! sql if $ofs != 0 >
<! sql query "move $ofs in tmp" >
<! sql endif >
<! sql query "fetch $step in tmp" q1 >
<! sql if $NUM_ROWS != 0 >
<table>
<tr> <th>Nombre</th> <th>Apellidos</th> <th>N�mero de tel�fono</th> <th>Correo electr�nico</th></tr>
<! sql print_rows q1 "<tr> <td>@q1.0</td> <td>@q1.1</td> <td><CENTER>@q1.2<CENTER></td> <td>@q1.3</td></tr>\n" >
</table>
<! sql if $step-1 < $ofs >
<! sql print "<a href=\"listin.pgsql\?ofs=" >
<! sql eval $ofs - $step >
<! sql print "\">">Anterior</a>
<! sql else >
Anterior
<! sql endif >
<! sql if $NUM_ROWS = $step >
<! sql print "<a href=\"listin.pgsql\?ofs=" >
<! sql eval $ofs + $step >
<! sql print "\">">Siguiente</a>
<! sql else >
Siguiente
<! sql endif >
</center>
<! sql endif >
<! sql free q1 >
<! sql query "end" >
<! sql close >
</protect>

PIE LISTADO 6: List�n de los usuarios de la base de datos.

LISTADO 7-

#use wml::exalumnos::plantilla title="B�squeda de antiguos alumnos en empresas" autorizacion
<H1>B�squeda de antiguos alumnos en la empresa
<! sql print "$empresa">
</H1>
<protect>
<! sql connect localhost nobody >
<! sql database exalumnos >
<! sql setdefault ofs 0 >
<! sql query "begin" >
<! sql query "declare tmp cursor for select nombre_persona, apellidos_persona from persona, trabaja_en where persona.dni=trabaja_en.dni and strpos(upper(trabaja_en.nombre_empresa),upper('$empresa')) >0 order by apellidos_persona" >

<! sql if $ofs != 0 >
<! sql query "move $ofs in tmp" >
<! sql endif >
<! sql query "fetch 10 in tmp" q1 >
<! sql if $NUM_ROWS != 0 >
<table>
<tr> <th>Nombre</th> <th>Apellidos</th></tr>
<! sql print_rows q1 "<tr> <td>@q1.0</td> <td>@q1.1</td>\n" >
</table>
<br>
<! sql if 9 < $ofs >
<! sql print "<a href=\"busca_trabajadores.pgsql\?empresa=$empresa&ofs=" >
<! sql eval $ofs - 10 >
<! sql print "\">">Anterior</a>
<! sql else >
Anterior
<! sql endif >
<! sql if $NUM_ROWS = 10 >
<! sql print "<a href=\"busca_trabajadores.pgsql\?empresa=$empresa&ofs=" >
<! sql eval $ofs + 10 ><! sql print "\">">Siguiente</a>
<! sql else >
Siguiente
<! sql endif >
<! sql else >
<P>No se ha encontrado ning�n trabajador de esa empresa</P>.
<! sql endif >
<! sql free q1 >
<! sql query "end" >
<! sql close >
</protect>

PIE LISTADO 7: B�squeda de personas en empresas

7. Capturas

8. Notas de maquetaci�n

Por favor, el esquema entidad relaci�n ha de verse, en el n�mero 14 no se le�a nada de �ste, por esto (y porque me han llegado varios mails de queja al respecto) la vuelvo a incluir en este art�culo.

9. Notas de coordinaci�n