Download bd3-0 - TLDP-ES

Document related concepts

Microsoft SQL Server wikipedia , lookup

PL/SQL wikipedia , lookup

PL/PgSQL wikipedia , lookup

Inyección SQL wikipedia , lookup

SQL Server Compact wikipedia , lookup

Transcript
1 Introducción
#$+
KComo
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:
 una parte de introducción de información que sirva como alta de los nuevos
usuarios.
 una sección de autenticación que permita acceder a los usuarios reconocidos
al área privada del servidor.
 una sección de consultas, sólo accesible por los usuarios reconocidos, que
permitirá obtener información de la base de datos
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
#$+
KYa
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:
 connect: permite conectarse a un servidor de base de datos indicando el
nombre del servidor y el del usuario (y contraseña) utilizados para acceder a
ésta. Si no se da nombre de usuario se utilizará uno por defecto.
 database: indica la base de datos del sistema de base de datos a utilizar, y es
absolutamente necesario para llegar a conectar a una base de datos.
 close: cierra la conexión a la base de datos, debe ser el último comando a
ejecutar.
 query: permite hacer una consulta SQL cualquiera a la base de datos y
devolver los resultados a través de un elemento que podrá utilizarse para
extraerlos.
 set,setdefault y setexpr: permite trabajar con variables dentro de
WWW-SQL, asignándolas valores. Se pueden modificar las variables y
comparar a través de un conjunto de operandos que incluyen, incluso,
expresiones regulares.
 free,fetch y seek: permite hacer operaciones sobre los elementos devueltos
del resultado de las consultas.
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:
[lt
[lt
[lt
[lt
[lt
[lt
]!-- Cabeceras HTML --[gt
]
]!sql connect[gt
]
]!sql database dbname[gt
]
]!-- código HTML y órdenes www-sql --[gt
]!sql close[gt
]
]!-- Pie HTML --[gt
]
]
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.
#$+
KEl
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.#KEl 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:
 comprobar que los datos tienen el formato adecuado.
 introducir estos datos en la base de datos y detectar los problemas que
puedan surgir.
 decidir si seguir adelante solicitando más datos y proceder si es necesario.
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:
 seleccionar la empresa en la que está trabajando de una lista de empresas
en la base de datos, para ello genera la lista en tiempo de ejecución de las
que ya existen.
 introducir los datos de una nueva empresa que no esté en la lista mostrada.
************** 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.#KPara 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":
 Autenticación basada en el servidor, en el que será éste el encargado de
gestionar las sesiones y autenticar debidamente a los usuarios. Este tipo de
autenticación se puede activar en Apache a través de ficheros .htaccess con
el módulo mod[lowbar]auth.
 Autenticación basada en el cliente, en el que será éste el encargado de enviar
al servidor una "prueba" de que es un cliente registrado.
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[lowbar]auth[lowbar]sql)
para poder utilizar cualquier base de datos en el primer caso.
Uso de cookies.K
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:
 Utilizar un protocolo seguro (un servidor https) de forma que el intercambio de
información entre cliente y servidor vaya cifrado y sea difícil de interceptar.
 cifrar la cookie e incluir información en ésta relacionada con el ordenador que
está accediendo (su dirección IP por ejemplo). De forma que otro cliente no
pueda interceptarla y usarla con éxito.
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#KFinalmente, 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:
 Generar una listas de personas registradas por año de promoción.
 Generar un listín de las personas registradas con su teléfono y dirección de
correo electrónico.
 Buscar una persona determinada en la base de datos.
 Generar una lista de personas y empresas en las que trabajan.
 Buscar información de las personas que están trabajando en una determinada
empresa.
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[lowbar]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
#$+
KCon
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
#$+
K
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
#$+
K
LISTADO 1-
[lt
]HTML[gt
]
[lt
]HEAD[gt
]
[lt
]TITLE[gt
]Alta de usuario[lt
]/TITLE[gt
]
[lt
]! sql if "$dni" == ""[gt
]
[lt
]! sql print "Error: Debe dar un DNI"[gt
]
[lt
]! sql setexpr alta 0[gt
]
[lt
]! sql else[gt
]
[lt
]! sql connect localhost jfs[gt
]
[lt
]! sql database exalumnos[gt
]
[lt
]! sql query "begin"[gt
]
[lt
]! 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')"[gt
]
[lt
]! sql query "end"[gt
]
[lt
]! sql print "[lt
]META http-equiv=Set-Cookie
content=dni="$dni;" path=/[gt
]" [gt
]
[lt
]! sql print "[lt
]META http-equiv=Set-Cookie2
content=dni="$dni;" path=/[gt
]" [gt
]
[lt
]! sql if "$email" != ""[gt
]
[lt
]! sql query "begin"[gt
]
[lt
]! sql query "insert into usa_mail (dni, e_mail)
values ( $dni, '$email')"[gt
]
[lt
]! sql query "end"[gt
]
[lt
]! sql endif[gt
]
[lt
]! sql if "$telefono" != ""[gt
]
[lt
]! sql query "begin"[gt
]
[lt
]! sql query "insert into usa_tfo (dni, telefono,
prefijo) values ( $dni, '$telefono', '$prefijo')"[gt
]
[lt
]! sql query "end"[gt
]
[lt
]! sql endif[gt
]
[lt
]! sql setexpr alta 1[gt
]
[lt
]! sql if "$trabajo" == "y"[gt
]
[lt
]! sql print "[lt
]META http-equiv=refresh
content=1;URL=alta_empresa.html[gt
]" [gt
]
[lt
]! sql endif[gt
]
[lt
]BODY[gt
]
[lt
]! sql if $alta == 1[gt
]
[lt
]! sql print "Su solicitud ha sido aceptada."[gt
]
[lt
]! sql if "$trabajo" == "y"[gt
]
[lt
]! sql print "[lt
]A HREF=alta_empresa.html[gt
]Dé de alta a su empresa[lt
]/A[gt
]." [gt
]
[lt
[lt
[lt
[lt
[lt
[lt
]! sql endif[gt
]! sql close[gt
]! sql endif[gt
]! sql endif[gt
]/BODY[gt
]
]/HTML[gt
]
]
]
]
]
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"
[lt
]H1[gt
]Dé de alta su empresa en la Base de
Datos:[lt
]/H1[gt
]
[lt
]BR[gt
]
[lt
]FORM METHOD="GET"
ACTION="alta_empresa.pgsql"[gt
]
Su puesto dentro de la empresa: [lt
]INPUT TYPE="TEXT"
NAME="puesto"[gt
][lt
]BR[gt
]
Su departamento dentro de la empresa: [lt
]INPUT
TYPE="TEXT" NAME="departamento"[gt
][lt
]BR[gt
]
[lt
]HR[gt
]
[lt
]protect[gt
]
[lt
]! sql connect localhost nobody [gt
]
[lt
]! sql database exalumnos [gt
]
[lt
]! sql query "begin" [gt
]
[lt
]! sql query "declare tmp cursor for select
nombre_empresa from empresa" [gt
]
[lt
]! sql if $NUM_ROWS != 0 [gt
]
[lt
]! sql query "fetch all in tmp" q1 [gt
]
Busque su empresa: [lt
]SELECT NAME="empresa"[gt
]
[lt
]OPTION VALUE="" DEFAULT[gt
]
[lt
]! sql print_rows q1 "[lt
]OPTION
[email protected][gt
]@q1.0"[gt
]
[lt
]/SELECT[gt
][lt
]BR[gt
]
[lt
]! sql endif [gt
]
[lt
]! sql free q1 [gt
]
[lt
]! sql query "end"[gt
]
[lt
]/protect[gt
]
[lt
]STRONG[gt
]Sólo si su empresa no está en la
lista previa introduzca los datos de ésta:[lt
]/STRONG[gt
][lt
]BR[gt
]
Nombre de la empresa: [lt
]INPUT TYPE="TEXT"
NAME="nombre"[gt
][lt
]BR[gt
]
Dirección:
Calle: [lt
]INPUT TYPE="TEXT" NAME="calle"[gt
][lt
]BR[gt
]
Ciudad: [lt
]INPUT TYPE="TEXT" NAME="ciudad"[gt
][lt
]BR[gt
]
País: [lt
]INPUT TYPE="TEXT" NAME="pais"[gt
][lt
]BR[gt
]
Código postal: [lt
]INPUT TYPE="TEXT"
NAME="codigo_postal"[gt
][lt
]BR[gt
]
Actividad: [lt
]INPUT TYPE="TEXT" NAME="actividad"[gt
][lt
]BR[gt
]
Número aproximado de empleados: [lt
]INPUT TYPE="TEXT"
NAME="empleados"[gt
][lt
]BR[gt
]
[lt
[lt
[lt
[lt
]INPUT TYPE="SUBMIT" VALUE="Dar de Alta"[gt
]/FORM[gt
]
]/BODY[gt
]
]/HTML[gt
]
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
[lt
]protect[gt
]
[lt
]! sql connect localhost jfs [gt
]
[lt
]! sql database exalumnos [gt
]
[lt
]! sql query "begin" [gt
]
[lt
]! sql if $empresa = "" [gt
]
[lt
]! 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 )" [gt
]
[lt
]! sql else [gt
]
[lt
]! sql set nombre "$empresa" [gt
]
[lt
]! sql endif [gt
]
[lt
]! sql query "insert into trabaja_en (dni,
nombre_empresa, puesto ,departamento)
values ( '$dni', '$nombre', '$puesto', '$departamento')"
[gt
]
[lt
]! sql query "end" [gt
]
[lt
]! sql print "[lt
]H1[gt
]Solicitud
aceptada[lt
]/H1[gt
]"[gt
]
[lt
]! sql print "[lt
]P[gt
]Se han registrados
sus datos asi como los de la empresa en los que trabaja.
"[lt
]/P[gt
][gt
]
[lt
]! sql print "[lt
]P[gt
]Gracias por darse
de alta[lt
]/P[gt
]."[gt
]
[lt
]! sql close[gt
]
[lt
]/protect[gt
]
PIE LISTADO 3: Alta de una empresa
LISTADO 4-
[lt
[lt
[lt
]
]HTML[gt
]HEAD[gt
]TITLE[gt
]
]
]Acceso de usuario[lt
]/TITLE[gt
[lt
]! sql setdefault dni 0 [gt
]
[lt
]! sql if $dni == 0 [gt
]
[lt
]! sql print "[lt
]META http-equiv=refresh
content=1;URL=respuesta/rechazado.html[gt
]" [gt
]
[lt
]! sql setexpr aceptado 0 [gt
]
[lt
]! sql else [gt
]
[lt
]! sql connect localhost nobody [gt
]
[lt
]! sql database exalumnos [gt
]
[lt
]! sql query "begin" [gt
]
[lt
]! sql query "declare tmp cursor for select * from
persona where dni=$dni and fecha_nacimiento='?fecha'" [gt
]
[lt
]! sql query "fetch 10 in tmp" q1 [gt
]
[lt
]! sql query "end" [gt
]
[lt
]! sql free q1 [gt
]
[lt
]! sql if $NUM_ROWS != 0 [gt
]
[lt
]! sql print "[lt
]META
http-equiv=refreshcontent=1;URL=respuesta/aceptado.htm
l[gt
]" [gt
]
[lt
]! sql print "[lt
]META http-equiv=Set-Cookie
content=dni=$dni;path=/[gt
]" [gt
]
[lt
]! sql print "[lt
]META http-equiv=Set-Cookie2
content=dni=$dni;path=/[gt
]" [gt
]
[lt
]! sql setexpr aceptado 1 [gt
]
[lt
]! sql else [gt
]
[lt
]! sql print "[lt
]META http-equiv=refresh
content=1;URL=respuesta/rechazado.html[gt
]" [gt
]
[lt
]! sql setexpr aceptado 0 [gt
]
[lt
]! sql close[gt
]
[lt
]! sql endif [gt
]
[lt
]! sql endif [gt
]
[lt
[lt
]/HEAD[gt
]BODY[gt
]
]
[lt
]! sql if $aceptado == 0 [gt
]
[lt
]! sql print "Lo siento su petición ha sido [lt
]A HREF=respuesta/rechazado.html[gt
]rechazada[lt
]/A[gt
]." [gt
]
[lt
]! sql else [gt
]
[lt
]! sql print "Su petición ha sido [lt
]A
HREF=respuesta/aceptado.html[gt
]aceptada[lt
]/A[gt
]." [gt
]
[lt
]! sql endif [gt
]
[lt
[lt
]/BODY[gt
]/HTML[gt
]
]
PIE LISTADO 4: Autenticación de un usuario
LISTADO 5-
[lt
]! sql setdefault dni 0 [gt
]
[lt
]! sql if dni == 0 [gt
]
[lt
]H1[gt
]Error[lt
]/H1[gt
]
[lt
]P[gt
]No conozco su DNI. Vaya a la [lt
]A
HREF=$(USER)/alta.html[gt
]página de altas[lt
]/A[gt
] si aún no se ha dado de alta o a la [lt
]A
HREF=$(USER)/acceso.html[gt
]página de acceso[lt
]/A[gt
] si no ha sido autentificado por el
servidor.[lt
]/P[gt
]
[lt
]protect[gt
]
[lt
]! sql else [gt
]
[lt
]/protect[gt
]
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
[lt
]H1[gt
]Listín de antiguos alumnos[lt
]/H1[gt
]
[lt
]protect[gt
]
[lt
]! sql connect localhost nobody [gt
]
[lt
]! sql database exalumnos [gt
]
[lt
]! sql setdefault ofs 0 [gt
]
[lt
]! sql setdefault step 10 [gt
]
[lt
]! sql query "begin" [gt
]
[lt
]! 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" [gt
]
[lt
]! sql if $ofs != 0 [gt
]
[lt
]! sql query "move $ofs in tmp" [gt
]
[lt
]! sql endif [gt
]
[lt
]! sql query "fetch $step in tmp" q1 [gt
]
[lt
]! sql if $NUM_ROWS != 0 [gt
]
[lt
]table[gt
]
[lt
]tr[gt
] [lt
]th[gt
]Nombre[lt
]/th[gt
] [lt
]th[gt
]Apellidos[lt
]/th[gt
] [lt
]th[gt
]Número de teléfono[lt
]/th[gt
] [lt
]th[gt
]Correo electrónico[lt
]/th[gt
][lt
]/tr[gt
]
[lt
]! sql print_rows q1 "[lt
]tr[gt
] [lt
]td[gt
]@q1.0[lt
]/td[gt
] [lt
]td[gt
]@q1.1[lt
]/td[gt
] [lt
]td[gt
][lt
]CENTER[gt
]@q1.2[lt
]CENTER[gt
][lt
]/td[gt
] [lt
]td[gt
]@q1.3[lt
]/td[gt
][lt
]/tr[gt
]" [gt
]
[lt
]/table[gt
]
[lt
]! sql if $step-1 [lt
] $ofs [gt
]
[lt
]! sql print "[lt
]a href=listin.pgsqlofs=" [gt
]
[lt
]! sql eval $ofs - $step [gt
]
[lt
]! sql print "[gt
]"[gt
]Anterior[lt
]/a[gt
]
[lt
]! sql else [gt
]
Anterior
[lt
]! sql endif [gt
]
[lt
]! sql if $NUM_ROWS = $step [gt
]
[lt
]! sql print "[lt
]a href=listin.pgsqlofs=" [gt
]
[lt
]! sql eval $ofs + $step [gt
]
[lt
]! sql print "[gt
]"[gt
]Siguiente[lt
]/a[gt
]
[lt
]! sql else [gt
]
Siguiente
[lt
]! sql endif [gt
]
[lt
]/center[gt
]
[lt
]! sql endif [gt
]
[lt
]! sql free q1 [gt
]
[lt
]! sql query "end" [gt
[lt
]! sql close [gt
]
[lt
]/protect[gt
]
]
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
[lt
]H1[gt
]Búsqueda de antiguos alumnos en la
empresa
[lt
]! sql print "$empresa"[gt
]
[lt
]/H1[gt
]
[lt
]protect[gt
]
[lt
]! sql connect localhost nobody [gt
]
[lt
]! sql database exalumnos [gt
]
[lt
]! sql setdefault ofs 0 [gt
]
[lt
]! sql query "begin" [gt
]
[lt
]! 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('$empres
a')) [gt
]0 order by apellidos_persona" [gt
]
[lt
]! sql if $ofs != 0 [gt
]
[lt
]! sql query "move $ofs in tmp" [gt
]
[lt
]! sql endif [gt
]
[lt
]! sql query "fetch 10 in tmp" q1 [gt
]
[lt
]! sql if $NUM_ROWS != 0 [gt
]
[lt
]table[gt
]
[lt
]tr[gt
] [lt
]th[gt
]Nombre[lt
]/th[gt
] [lt
]th[gt
]Apellidos[lt
]/th[gt
][lt
]/tr[gt
]
[lt
]! sql print_rows q1 "[lt
]tr[gt
] [lt
]td[gt
]@q1.0[lt
]/td[gt
] [lt
]td[gt
]@q1.1[lt
]/td[gt
]" [gt
]
[lt
]/table[gt
]
[lt
]br[gt
]
[lt
]! sql if 9 [lt
] $ofs [gt
]
[lt
]! sql print "[lt
]a
href=busca_trabajadores.pgsqlempresa=$empresa[amp
]ofs=" [gt
]
[lt
]! sql eval $ofs - 10 [gt
]
[lt
]! sql print "[gt
]"[gt
]Anterior[lt
]/a[gt
]
[lt
]! sql else [gt
]
Anterior
[lt
]! sql endif [gt
]
[lt
]! sql if $NUM_ROWS = 10 [gt
]
[lt
]! sql print "[lt
]a
href=busca_trabajadores.pgsqlempresa=$empresa[amp
]ofs=" [gt
]
[lt
]! sql eval $ofs + 10 [gt
][lt
]! sql print
"[gt
]"[gt
]Siguiente[lt
]/a[gt
]
[lt
]! sql else [gt
]
Siguiente
[lt
]! sql endif [gt
]
[lt
]! sql else [gt
]
[lt
]P[gt
]No se ha encontrado ningún trabajador de
esa empresa[lt
]/P[gt
].
[lt
]! sql endif [gt
]
[lt
]! sql free q1 [gt
]
[lt
]! sql query "end" [gt
]
[lt
]! sql close [gt
]
[lt
]/protect[gt
]
PIE LISTADO 7: Búsqueda de personas en empresas
7 Capturas
#$+
K
 Figura 1 - entidadrel.png Pie: Esquema entidad relación del proyecto- #K
 Figura 2 - esq-servidor.png. Pie: Esquema simplificado del servidor a diseñar.
#K
 Figura 3 - cap-servidor.png. Pie: Página de alta de un usuario en el servidor.
#K
8 Notas de maquetación
#$+
K
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
K
T
OC_0
ntroducci_n
b
rowse
Intro
ducción
T
OC_1
W
WW_SQL
b
rowse
WWW
-SQL
T
OC_2
D
esarrollo_del_servidor_
b
rowse
Des
arrollo del servidor.
T
OC_3
Alt
a de usuarios.
T
OC_4
Auten
ticación.
U
so de cookies.
T
OC_5
I
Consultas
T
OC_6
onclusiones
b
rowse
Conc
lusiones
T
OC_7
S
umarios
b
rowse
S
umarios
T
OC_8
L
istados
b
rowse
L
istados
T
OC_9
C
apturas
b
rowse
C
apturas
e
ntidadrel
e
ntidadrel
e
sqservidor
e
sqservidor
c
apservidor
C
#$+
c
apservidor
OC_10
N
otas_de_maquetaci_n
b
rowse
N
otas de maquetación
T
OC_11
N
otas_de_coordinaci_n
b
rowse
N
otas de coordinación
T