Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Estimado lector
Para el XVII Evento Internacional de Usuarios GeneXus, realizado en
setiembre de 2007, nos pidieron escribir un libro de gil y amena lectura sobre
la versin de GeneXus que se encontraba en plena gestacin: la entonces
denominada versin Rocha, hoy la X, una verdadera refundacin del producto.
Desde ese entonces la X ha crecido mejorando funcionalidades e
incorporando algunas otras. Por esa razn, sentimos la necesidad de adaptar
aquella primera edicin de nuestro libro GeneXus Rocha Episodio Uno
para que siga cumpliendo con su objetivo inicial: mostrar GeneXus a quien,
nuevo en esta herramienta, tenga inquietud o deseos de descubrirla, as como a
quien, conocedor de versiones anteriores, quiera redescubrirla en esta nueva y
fundamental etapa que inicia.
He aqu entonces la segunda edicin actualizada de aquel libro. Fue
elaborada con GeneXus X, upgrade 4. Actualmente, Artech se encuentra
trabajando para liberar en unos meses ms GeneXus X Evolution 1, que incluye
nuevas e importantes funcionalidades, como el permitir generar, adems de
aplicaciones Web, aplicaciones Win.
Esperamos que pueda ir siguiendo las pginas de este libro con el mismo
entusiasmo que nos llev a escribirlas, y que pueda adaptar la lectura a sus
ganas y necesidades. Hay captulos ms tcnicos que otros, en especial el 3 que
trata sobre Patterns. No pudimos ceder ante la tentacin de mostrar toda su
potencia, lo que nos llev a desnudar cada vez un poquito ms. Quien quiera
mucho, lo leer todo, quien no, lo leer ms superficialmente. Tmese esa
libertad, que fue la que nos permiti dar rienda suelta a nuestras ganas de
contar. Los ltimos captulos probablemente sean los ms giles y disfrutables.
Para entender ms cabalmente lo explicado, sugerimos ir realizando con la
versin Trial de GeneXus, de distribucin gratuita (www.genexus.com/trial), la
aplicacin que nuestros personajes irn desarrollando a lo largo del libro. Si
bien podr elegir el generador y DBMS que prefiera, si es usted nuevo en
GeneXus, le recomendamos elegir los default que son lo que utilizarn nuestros
Los autores.
Montevideo, Mayo de 2009.
Sinopsis
Captulo 1: El encuentro. Diego y Mary se reencuentran luego de aos sin
verse, dando inicio a esta historia de encuentroscon GeneXus.
Captulo 2: rase una vezun Proyecto. Julia, Mike y Diego definen e
inician el anlisis y desarrollo del sistema para una agencia de viajes, a la vez
que Diego acompaa a Mary, caf mediante, en su primera experiencia de
acercamiento al IDE y a la creacin de los primeros objetos del proyecto.
Captulo 3: Hecho a mquina, configurado a mano. Mientras Julia va
haciendo uso de lo mximo en capacidad de productividad gracias a los
patterns, Diego da rienda suelta a su creatividad poniendo de manifiesto que
los deseos de los clientes no siempre deben ser un duro escollo a sortear.
Captulo 4: Vuelo al mundo de los Subtipos. A velocidad match 3, Diego
ensea a Mary, esta vez en su oficina y no en el bar, por qu los subtipos son la
solucin ideal al problema de las ambigedades que se pueden presentar en un
modelo de datos, mientras pone el punto final a las ltimas transacciones.
Captulo 5: Cuando el qu no alcanza. El inters de Mary pareca ir in
crescendo. Encuentros frecuentes en la oficina o en el bar. Preguntas todava
sin respuesta. Las transacciones permiten declarar, pero qu pasa con los
procesos batch? Procedimientos GeneXus. Despus, ms declaraciones:
Business Components. Y cmo realizar reportes pdf? Atracciones que invitan.
Invitaciones que atraen. Una cena en ciernes Y las consultas dinmicas por
ejemplo?
Captulo 6: Ms declaraciones. Data Providers para permitir cargar y
devolver una salida estructurada, sin programar, sino declarando intenciones.
Diego declara sus intenciones. Debe enviar un xml a la aerolnea.
Captulo 7: Soplan nuevos vientos. Su casa (la de ella), vino, msica, su
nerviosismo (el de l) y ms GeneXus. Sabemos que todo tiene un final, pero lo
que Diego apenas sospechaba, era que esto poda llegar a ser el principio de
algo ms.
Captulo 1
El encuentro
Alguien cuenta que esperando por fin ser atendido en un banco, escuch
casualmente una conversacin entre un hombre y una mujer, que tambin
esperaban. Segn pareca, se reencontraban luego de aos sin verse; antiguos
compaeros de estudio?
Cmo ests Mary? Cmo van tus cosas? Sigues trabajando donde
siempre?dijo el hombre con voz profunda, impostada, mirada fija, aire
seductor.
Bueno Diego, luego de tantos aos trabajando en la empresa, logr
ascender y ahora soy Developer Team Manager desde hace ya dos aos dijo
la mujer de rostro sensiblemente cansado.
Supongo que debo felicitarte, pero por qu esa cara? tienes
problemas en el departamento? He escuchado que los sistemas de ustedes,
adems de ser de gran porte, son fiables
Lo son, pero no sabes lo que cuesta su mantenimiento. Me estoy
enfermando, Diego, no duermo bien; muchas responsabilidades, grandes cargas
horarias, poco descanso. Siento en el pecho
una presin complet Diego Entiendo, Mary dijo al tiempo
que depositaba su mano derecha sobre el brazo izquierdo de ella-. Cmo estn
trabajando? Qu herramientas estn usando?
Y de todo un poco, lo usual al final todo es lo mismo contest
Mary ajena a esa cercana- Tengo un equipo importante de personas trabajando
en los desarrollos y mantenimientos, pero an as no damos abasto.
Bueno, no todo es lo mismo Qu te parece si terminamos este
trmite aqu y vamos a tomar un caf y me sigues contando? pregunt Diego a
la vez contento y turbado.
GeneXus?
Ya en el bar, caf mediante, Diego escuchaba atentamente a una Mary
angustiada. Recordaba su antigua firmeza, su empuje. Senta un egosta dejo de
alegra de poder ser ahora l quien la ayudara.
En cuntos proyectos estn? pregunt Diego para instaurar un
clima confesional.
Ahora en uno solo. Pero es ms que nada en tareas de mantenimiento.
Nuestros clientes nos estn solicitando cosas nuevas todo el tiempo, pero nos
est siendo imposible satisfacer nuevos requerimientos. Adems, esta tarea de
mantenimiento es realmente costosa, y ya no puedo justificar a la Direccin la
incorporacin de ms recursos humanos; nos saldramos del punto de
equilibrio.
No ser que los sistemas estn un poco anticuados, tecnolgicamente
hablando? No les convendra hacer una reingeniera de todo a nuevo?
pregunt Diego con liviandad.
S, eso quisiera, y eso he propuesto. Pero los tiempos realmente no nos
dan, y como te dije, puede que estemos ya pasados de costos. No s qu voy a
hacer estoy agotada Diego, me siento en un callejn sin salida.
Mary, no desesperes, sabes cuntos estn como t? Tu caso es uno
ms entre muchos. Las aplicaciones son cada vez ms complejas, y con las
herramientas manuales de las que disponamos, se est tornando imposible
desarrollar y peor an, mantener esos sistemas, pues se estn volviendo
inmanejables. Pero no todo es negro, Mary. Hoy en da hay soluciones. La
alternativa es delegar en procesos automticos el trabajo que hacemos los
humanos, de manera que podamos dedicarnos a las nuevas complejidades y no
a tareas como la codificacin que pueden ser efectuadas por un programa.
Nosotros, sin ir ms lejos, estamos llevando adelante varios proyectos
importantes en simultneo, y no tenemos demasiados inconvenientes. Conoces
algo de GeneXus?
Ah, GeneXus. S, algo he escuchado, pero no he tenido tiempo de
interiorizarme demasiado Ustedes trabajan con esa herramienta? He odo
10
que cada vez ms gente no tcnica puede usarla, lo que me despierta cierta
curiosidad.
Mira Mary, no s si GeneXus sea la panacea, pero s s que cura
varias de las dolencias que tienen empresas como la tuya. Es un programa que
hace programas. Automatiza la construccin y mantenimiento de tus
aplicaciones y de tu base de datos. Obviamente est en un nivel de abstraccin
superior a otras herramientas, comprendes? Contstame a esta pregunta: si t
pudieras disponer de un software que te permitiera lograr hacer esto
automticamente, lo usaras?
Absolutamente... Se incorpor en su silla. S, justamente se es
nuestro problema. Tenemos que hacer casi todo a mano
La gran dificultad de la empresa de Mary, pens Diego, era el de tantas
otras: imposibilidad de enfrentar nuevos proyectos porque los tiempos de
mantenimiento de los sistemas actuales, fundamentados en metodologas
tradicionales, lo impedan. Y eso, para una empresa que vive del desarrollo, es
una luz roja de peligro.
Bueno, no lo diga en voz alta, pero usted, estimado lector, se estar
preguntando: Cmo?
Cmo? pregunt ya ms vital.
No te parece razonable pensar que dado un conjunto de visiones de
datos, - se interrumpi Diego con cierta malicia - exista un nico modelo
relacional mnimo que lo satisfaga?
Hmmm puede ser, no estoy segura. Pero qu tiene esto que ver con
mis problemas de mantenimiento?
Y si eso es cierto continu Diego, ignorando la vacilacin de su
compaera- no te parece posible encontrar un procedimiento de ingeniera
inversa que partiendo de ese conjunto de visiones d como resultado el
esquema de esa base de datos relacional mnima? Bueno, si me vas a decir ver
para creer, con gusto acepto una apuesta, como en los viejos tiempos; pero
desde ya te adelanto: vas a perder.
11
Una Apuesta
El objetivo de GeneXus es (a travs de la descripcin de las visiones de los
usuarios) conseguir un muy buen tratamiento automtico del conocimiento de los
sistemas de negocios..
Breogn Gonda & Nicols Jodal
13
14
menos posible. En GeneXus vas a tener algn cdigo que ser procedural, pero
el lenguaje en que lo escribes, no es el lenguaje al que ests acostumbrada en
l tampoco tienes que nombrar tablas, ni ndices, ni nada de lo fsico de una
base de datos.
Pero no entiendo entonces dnde entra el Modelo Relacional
pregunt Mary confundida.
Es el que se utiliza para representar y manipular los datos: es el
modelo interno o fsico, pero no ser creado por ti, ser inferido por GeneXus
con su procedimiento de ingeniera inversa. Mi apuesta fue tramposa.
Y cmo describes las visiones de los usuarios, el Modelo Externo, de
manera que pueda aplicarse ingeniera inversa sobre ellas y obtener todo eso
que dices? Porque tiene que ser lo bastante formal y rigurosa esa descripcin
como para que no haya ambigedades y que un programa pueda inferir todo
eso que los programadores hacemos todava a mano.
S, lo es. Las descripciones se realizan a travs de determinados
objetos-tipo de GeneXus que indican el qu. A travs de ellos, GeneXus
encuentra el cmo. Por lo que, para aprender a usar GeneXus, tienes que
aprender a describir, a usar esos objetos-tipo. No necesitas grandes
conocimientos tcnicos; cada vez menos.
Diego continuaba hablando, llenando el reducido silencio que su
interlocutora haba dejado. A pesar de tantos aos sin verse, conoca bien a
Mary, conoca esa expresin de ojos pensativos, y saba que su silencio lo
invitaba a proseguir. No poda tener mejor suerte - Bendito GeneXus! - pens,
y continu en tono confidente, manejando las pausas, seguro de lograr los
efectos buscados.
15
16
Diego, debo irme, pero quiero saber ms. Me has dejado con la cabeza
confusa. Es muy grande el cambio de mentalidad, quisiera palpar esto ms de
cerca, verlo funcionando. Te parece de encontrarnos la semana prxima,
misma hora, mismo lugar?
Ciertamente expres Diego en tono pretendidamente sereno.
17
18
Captulo 2
19
El tiempo es tirano
Un breve tiempo atrs, los directores y el equipo de desarrollo se pusieron
de acuerdo en el objetivo de un proyecto a corto plazo, tres semanas o algo
as. El hecho de que iban a trabajar con GeneXus X, a sabiendas del gran
aumento de usabilidad y productividad que sta traa incorporado, les haba
permitido reducir a la mitad los plazos que normalmente pactaban con sus
clientes.
Cada usuario tiene una o mltiples visiones de los datos que utiliza
cotidianamente. Entre estas visiones, podemos pensar en un primer tipo: el
que agrupa aquellas que se utilizan para manipular los datos (introducirlos,
modificarlos, eliminarlos y visualizarlos en forma limitada), a estas visiones de
usuarios les hemos llamado Transacciones y constituyen el primer objeto-tipo
de GeneXus.
Breogn Gonda & Nicols Jodal
20
variados en el mundo. Qu les deca esto? Antes que nada, que si los
destinos eran puntos tursticos de ciudades distribuidas a lo largo y ancho del
mundo, deban disponer de un almacenamiento para ello.
Es as que el equipo completo se reuni y luego de intercambiar notas e
impresiones, concordaron en que Julia comenzara a describir las primeras
pautas obtenidas, mientras el resto, en especial Diego, comenzara a
representar en GeneXus aquellas visiones de los usuarios ms claramente
descriptas.
21
Panels
22
ofrece los nombres de las ltimas bases de conocimiento que han sido abiertas,
con sus fechas de ltima modificacin; note que tambin estn presentes links
que permiten abrir o crear una nueva base de conocimiento.
Debajo, un contenedor Extensions presenta herramientas desarrolladas por
Artech o terceros, que pueden ser instaladas y utilizadas libremente, y permiten
extender en todas direcciones la potencia de la herramienta.
El sector rotulado GeneXus Community, contiene sindicaciones de
contenidos de sitios Web vinculados a la Comunidad que se actualizan con
frecuencia (RSS). Note que debajo de cada noticia aparece More como link al
documento propuesto.
A su vez observe la celda Address que le permitir navegar por la Web o
por su sistema de archivos sin salir del IDE.
23
en Java tendrs que indicar cosas tales como dnde estarn las clases en la
webapp, algo que en .Net no tiene sentido. Es decir, en base al ambiente que
hayas elegido, te muestra propiedades necesarias para configurarlo, para que
GeneXus pueda luego decirte: sus deseos son rdenes y te implemente la
aplicacin como se lo pediste.
Casualmente, mientras Diego y Mary intercambiaban palabras y miradas en
el caf, Julia realizaba esos mismos pasos que lo invitamos a seguir a usted
tambin.
1. Seleccione File/New/Knowledge Base (o el link New Knowledge Base de la
Start Page). A continuacin ver en la pantalla el siguiente dilogo:
TravelAgency
24
Observe adems que la KB ser almacenada en una base de datos que por
defecto recibir el nombre GX_KB_nombre en la instalacin del
SQLServer local que usted tenga. Si no tiene una local, podr utilizar una
de la red. Presionando el botn [Advanced] podr modificar estos valores.
2. Pulse [Create]. GeneXus crear una base de conocimiento vaca, y usted
debera ver una imagen semejante a la que se observa a continuacin.
Files
Julia haba recibido por e-mail varios archivos de documento de los jefes de
seccin de cada departamento con requerimientos para el sistema, donde
listaban las prioridades y caractersticas de sus sectores, algunos flujos de
procesos, etc.
26
Como estos documentos ya estaban hechos por terceros, decidi que sera
importante incorporarlos en su estado original dentro de la base de
conocimiento, de forma tal que siempre estuvieran disponibles para su consulta.
Eran importantes las palabras de los usuarios expuestas por ellos mismos.
As, expandi el nodo Documentation del rbol y seleccion Files
abrindolo con doble clic. Como resultado, un nuevo tab apareci dentro de la
ventana principal, rotulado Files. All presion Add New File y se le abri una
ventana que le permiti explorar su sistema de archivos, y elegir cada archivo a
ser insertado en la KB. As qued el tab Files luego de esto.
Images
Tambin le haban enviado por e-mail el logo de la empresa, por lo que
accedi al nodo Customization del rbol del Folder View, abri haciendo doble
clic sobre Images el tab correspondiente e import, almacenndolo en la KB, el
archivo Logo.bmp que sera utilizado en el encabezado de las pginas de la
aplicacin. En ese mismo e-mail recibi decenas de archivos con imgenes
sobre atracciones tursticas que luego necesitaran almacenar en la base de
datos, por lo que momentneamente las guard tambin aqu, para tenerlas
centralizadas en la KB.
27
Main Document
Ahora Julia se apresta a empezar a escribir la pgina principal del wiki de la
KB: observe que bajo el nodo Documentation del rbol aparece un objeto Main
Document. Cada equipo de desarrollo tiene metodologas diferentes respecto a
la documentacin. En ACME utilizan esta pgina principal para describir las
generalidades del sistema bajo desarrollo, y para acceder desde aqu a los
distintos elementos de documentacin.
Tambin podra elaborarse aqu mismo el Plan Director del proyecto, en vez
de insertarlo como archivo. Pero usted y su equipo de desarrollo utilizar esta
pgina como mejor le parezca.
Julia abre Main Document y un nuevo tab aparece en la ventana principal,
rotulado Document:Main. Dado que lo que desea es comenzar a escribir, pulsa
el selector Edit que se encuentra al pie de la ventana y redacta (dndole
formato) lo que se observa en la siguiente imagen. Luego pulsa el selector
Preview y tiene la vista normalizada de lo que escribi. Guarda los cambios
(Preview se transforma en Browse).
Note que le ha dado algn formato al texto. Para ello se vali de la toolbar
formatting:
28
El IDE de GeneXus ofrece varios paneles con utilidades que se pueden acoplar en cualquier parte de la ventana y tambin se
pueden ocultar automticamente cuando pierden el foco para que no ocupen sitio en la ventana principal. Usted puede activarlas
mediante View/Other Tool Windows.
29
30
32
33
34
destino). Es decir, resulta evidente que deberemos crear una transaccin para
representar e ingresar la informacin de pases y sus ciudades, as como de las
categoras de atracciones existentes. Esos identificadores de los que me
preguntabas, sern, casualmente, los que identifiquen cada dato (instancia) de
estos.
A ver si entiendo: una vez que definas esas otras transacciones,
GeneXus inferir tablas para almacenar los datos que manipulan, y a partir de
all, se dar cuenta que esos atributos que colocaste en la estructura de la
transaccin Attraction, (AttractionCategoryId, CountryId y CityId) son los que
se traduciran en claves forneas en la tabla relacional asociada.
Sigues siendo la misma luz de siempre, Mary! exclam Diego con
ojos iluminados.
Pero entonces, qu hacen en esa estructura CountryName, CityName,
AttractionCategoryDescription? En un modelo relacional normalizado nunca
podran estar en esa tabla.
Es que no lo estarn. Por eso te deca que la estructura de una
transaccin no se corresponde exactamente con la de la tabla fsica asociada.
Ya te lo explicar, no quiero abrumarte con detalles. Traer mi notebook al
prximo encuentro porque lo habr, no? inquiri Diego vacilante, y
prosigui sin esperar respuesta, y te mostrar
Ahora el lector ver los pasos que sigui Diego en la creacin de la
transaccin mediante el IDE de GeneXus al da siguiente en su trabajo.
Primero que nada, seleccion el link New Object de la Start Page y
apareci a su vista la ventana cuyo dilogo permite la creacin de un objeto
dentro de la KB. De la caja Select a Type, con la lista de objetos GeneXus
disponibles, seleccion Transaction y luego, en la celda Name escribi el
nombre Attraction, quedando una imagen semejante a la que se muestra a
continuacin.
35
Los objetos que se abren en la ventana principal del IDE aparecen como tabs,
donde uno solo, el activo, se presenta en la ventana central. El objeto abierto
puede tener varios elementos o partes, en cuyo caso ser uno el activo en cada
oportunidad. En el tope inferior de la ventana aparece una barra de acceso que
permite, mediante Selectores, seleccionar otra de las partes del objeto activo.
36
Selectors
37
38
Definicin de Dominios
Diego hizo doble clic sobre el nodo Domains en el rbol del Folder View
tras lo cual se abri en la ventana principal el tab que muestra y permite editar
dominios. Ingres as los dominios Id y Name. El mecanismo es semejante al
de crear atributos en una transaccin.
2
En general en GeneXus existen varios caminos que le permiten realizar lo mismo, para que el efectuar su tarea le resulte
siempre cmodo.
39
3
En lo que sigue en este material, para diferenciar los nombres de las tablas de los de las transacciones usted ver a las tablas
escritas en maysculas.
40
4
Con GeneXus X usted podr generar exclusivamente aplicaciones Web 2.0. Para generar una aplicacin Win, podr utilizar
GeneXus X Evolution 1. All la transaccin presentar tambin un WinForm.
41
42
Podemos ver Attraction como link. Qu suceder cuando Diego haga clic
sobre el mismo? Se abrir un nuevo tab de documentacin, esta vez de la
transaccin, donde podr editarla, e incluso abrir la propia transaccin:
44
45
Obsrvese que aparecen nuevos dominios. Es de suponer que Diego los cre, o bien antes o bien en el mismo momento de
ingresar estos atributos, por ejemplo, al ingresar CountryFullName, en la columna Type pudo haber digitado: LongName =
Character(50) con el mismo resultado. Suponiendo que Diego ya tuviera definido un dominio Details como VarChar(500,200),
46
47
48
Observe que GeneXus nombra la tabla concatenando el nombre de la transaccin al nombre del
nivel: COUNTRYCITY
49
pantalla cuyo diseo ser el del WebForm, podr, por ejemplo, ingresar una
nueva atraccin (nuevo registro en la tabla ATTRACTION subyacente). Sera
deseable que cuando el usuario final colocara un identificador de pas en el
campo correspondiente a CountryId, y uno de ciudad en CityId pudiera
visualizar automticamente el nombre de dicho pas, CountryName y de dicha
ciudad, CityName. Es decir, que CountryName y CityName sean trados en
ejecucin de las tablas COUNTRY y COUNTRYCITY a travs de la clave
fornea {CountryId, CityId}. Para poder colocar en el form atributos a los que
se llega a travs de claves forneas, es necesario que estn presentes, inferidos,
en la estructura.
Qu sucedera si el usuario digitara para CountryId, CityId un par de
valores inexistentes? Y si mediante la transaccin Country se quisiera eliminar
una ciudad para la que existieran atracciones? Si se nos permitieran hacer estas
operaciones, se estara violando una de las condiciones ms importantes de los
modelos relacionales para mantener la consistencia de los datos: la integridad
referencial. De hecho GeneXus agregar automticamente en las transacciones
el cdigo necesario para realizar estos controles sin que el desarrollador se
moleste en hacerlo.
Integridad Referencial
Diego comunic a Julia que ya haba definido las dos primeras
transacciones. A los efectos de comprobar que el modelo reflejara la realidad,
ella hizo un Diagrama de Bachman (diagrama de relaciones entre tablas) sobre
las tablas inferidas por GeneXus a partir de las transacciones.
Para ello expandi el nodo Tables del contenedor Folder View, luego,
posicionada sobre cualquier tabla, puls el botn derecho para abrir el men
contextual y escogi New/Object, tras lo cual se abri la ventana Create New
Object donde seleccion el objeto Diagram para finalmente pulsar [Create].
Seleccion las tres tablas simultneamente y las arrastr hacia la hoja en
blanco, obteniendo el siguiente resultado.
50
51
52
concepto de tabla extendida. Una tabla que fsicamente no existe, pero que te la
imaginas.
Absolutamente cierto. Vers que utilizamos el concepto a lo largo y
ancho de GeneXus y por eso se le ha puesto un nombre.
Mientras Diego permaneca absorto en sus recuerdos, Julia comprob que
se cumplan correctamente las necesidades de acceso a la informacin entre las
tablas.
Mirando un Diagrama de Bachman es fcil determinar cul es la tabla extendida
de cada tabla (base). Todas las tablas a las cuales se pueda llegar siguiendo las
flechas de punta simple (relaciones N-1) desde la tabla base, formarn parte de
su tabla extendida. La tabla extendida no tiene existencia fsica, sino slo
conceptual. Nos permitir referirnos a la informacin unvocamente relacionada
con el registro en el que estemos posicionados.
Comenzando a Prototipar
Para poder dejarle paso a Mike, y que ste pueda comenzar a jugar su papel
de tester del proyecto, Diego puls <F5> para dar comienzo a la prototipacin.
Si desea modificar alguna de ellas, alcanza con seleccionar el panel Preferences del contenedor Knowledge Base Navigator y
all buscar la preferencia a configurar, por ejemplo el DBMS asociado, o el lenguaje de implementacin, etc. y con <F4> sus
propiedades (en la ventana que se abre).
53
8
Un sencillo men de prototipacin creado por GeneXus (es un xml conteniendo links a los distintos objetos GeneXus creados,
para poder invocarlos en forma fcil y rpida como se ver en breve).
54
Obsrvese que abajo se muestran las sentencias SQL que se utilizarn para reorganizar (en este caso crear) esa tabla.
55
cambios estructurales que GeneXus deber llevar a cabo sobre la base de datos
para dejarla en el nuevo estado, consistente con la KB.
De conformidad con el IAR, Diego puls [Create] dando paso a la
reorganizacin de la base de datos10. Como en este primer paso sta no exista,
se va a crear. Ser en sucesivos cambios que ser reorganizada, en tanto
reestructurada. Ahora bien, cundo se generan los programas?
Inmediatamente, listos para ser probados! Desde que Diego presion <F5> e
ingres la informacin que le faltaba a la plataforma (nombre de BD y
servidor), hasta que se le abri una ventana del Browser con el Developer
Menu listo para ejecutar, no pas ms de un minuto. Diego estudi
detenidamente unos listados desplegados por GeneXus antes, que le
permitieron ver que iba por buen camino pero no se apure, estimado lector,
que sobre este punto volveremos ms adelante y Mike est un poco ansioso por
entrar en escena.
10
56
57
Agregando conversacin
Entre los selectores que se presentan al abrir la documentacin, aparece
uno: Talk, que tiene por finalidad permitirnos crear un espacio donde establecer
un dilogo con otros usuarios sobre el objeto en cuestin.
a escribir, sta debe ser creada. Cuando Mike salve este espacio de memoria, se
generar una pgina con su contenido.
Al cliquear sobre el signo de interrogacin, cambi al estado de edicin e
ingres el texto, grab, y pudo ver:
59
11
Sin necesidad de entrar a la transaccin, tambin puede buscarse el atributo para editar sus propiedades con <F4>, a travs de
la ventana Attributes, que se accede mediante View/Work With Attributes. Las propiedades que se modifiquen de cualquiera de
las dos maneras aplican al atributo en general, no al atributo en una determinada transaccin en particular.
60
61
62
63
Reorganizando (reorg)
Diego cambi propiedades de dos atributos de la transaccin Country, esto
indirectamente disparar algn cambio en la tabla fsica? Veamos el siguiente
Impact Analysis Report que se observa luego de que pulsara <F5>:
64
65
Diego puede decidir pedirle a GeneXus que haga efectivamente los cambios
informados ([Reorganize]) o cancelar la reorganizacin, con lo cual la prxima
vez que se presione <F5> volver a realizarse el IAR. Elige reorganizar.
Al releer lo charlado en el Talk, con intenciones de contestar que todo fue
hecho, encuentra que Mike propona que por defecto todos los Ids de
transacciones fueran autonumerados. (Su confusin vino a raz de que Mike, en
lugar de haber documentado esto en el Talk del Main Document, lo hizo en el
de la transaccin Country). Pero entonces, para implementar lo sugerido,
tendra que ir una por una a cambiar la propiedad Autonumber de esos
atributos? No!, pronto record que todos ellos estaban basados en el dominio
Id. Alcanzaba con editar el dominio, sus propiedades y all, de igual manera
que se hizo para el atributo CountryId, encender la propiedad Autonumber a
nivel del dominio. Todos los atributos basados en el presente y en el futuro en
ese dominio, automticamente heredarn la propiedad!
Pero#@!#!@...!, maldijo en voz alta. CityId no es clave primaria
simple. Para dotar a un atributo con la caracterstica de autonumerado, ste
debe ser clave primaria simple. CityId es parte de la clave primaria de
COUNTRYCITY12.
Cmo hacer, entonces, para que este atributo no tome la propiedad
Autonumber como True dada a su dominio Id?13 Sencillo. Se editan las
propiedades del atributo CityId (como antes se hiciera con CountryId) y se
modifica la Autonumber, llevndola a False. Se est cambiando, pues, el
comportamiento por defecto dado por el dominio.
Lo mismo puede decirse del atributo AttractionCategoryId que por el
momento es de Attraction y no es clave primaria, aunque pronto lo ser cuando
Diego cree la nueva transaccin AttractionCategory, unos pasos ms adelante.
Por esta razn, decidi dejar la modificacin en la definicin del dominio Id
12
Para dar valores consecutivos a este atributo, habr, pues, que apelar a una regla: Serial. Le proponemos la investigue luego
de ver algunas reglas, en la seccin siguiente.
13
De todas formas, como GeneXus sabe de esta restriccin, si Diego no se hubiera percatado del problema, GeneXus
igualmente hubiera actuado con inteligencia y no hubiera definido el atributo en la base de datos con autonumber. A efectos
didcticos preferimos hacer trabajar a Diego.
66
67
Obsrvese que se est utilizando un mtodo de invocacin corriente en GeneXus: el Call, que est apareciendo aqu como una
regla. Tambin obsrvese que lo que precede al call es el nombre del objeto invocado, en nuestro caso ser otro objeto GeneXus
de tipo Procedimiento, y por ltimo, obsrvese que los eventos de disparo aparecen identificados en la sintaxis de una regla:
Rule if condition on Event
68
Sabiendo que lo nico que modific desde el anterior <F5> fue agregar
reglas a ambas transacciones, anticipa que cuando ahora vuelva a pulsar <F5>
no habr reorganizacin, pero s los pasos que siguen.
2. GeneXus da paso a la etapa de especificacin, que es un anlisis de todo lo
definido en cada uno de los elementos que componen los objetos que usted haya
cambiado, como por ejemplo, las estructuras, los forms, las reglas incorporadas, y
ms. Esta tarea da por resultado un listado de navegacin en el cual GeneXus
informa de la lgica que ha interpretado para cada objeto que haya sufrido
cambios desde el <F5> anterior, junto con advertencias y errores (en caso de
haberlos).
donde condition es una condicin booleana y Event es uno de los eventos de disparo vlidos, que invitamos al lector
interesado a buscar en las distintas fuentes de documentacin del producto. Listamos algunos: AfterValidate, BeforeInsert,
BeforeUpdate, BeforeDelete, AfterInsert, AfterUpdate, AfterDelete, BeforeComplete, AfterComplete, etc.
69
70
completa (si hay objetos que no han variado, y fueron generados en un <F5>
anterior, para qu hacerlo nuevamente?). La generacin implica la escritura de
lneas de cdigo que implementen la programacin de los objetos en el lenguaje
elegido por usted para el ambiente de desarrollo (por cada una de las dos
transacciones de Diego, se generar entre otras cosas un archivo .cs. No olvide
que l eligi C# como su lenguaje de desarrollo). Adems mientras el
desarrollador no cree su propio objeto principal, se crear un xml: el Developer
Menu, que contendr links a todos los programas (objetos) generados.
4.
Por ltimo, GeneXus compila los programas y ejecuta (hasta que no se cree un
objeto principal de la ejecucin) el Developer Menu en el Browser instalado en
esa mquina.
71
72
73
15
Y si Mike hubiese testado anteriormente la transaccin Attraction y hubiese insertado registros antes de esta reorganizacin?
Supngase que hubiera ingresado una atraccin con Id de categora 1 y descripcin Nightlife qu pasara entonces en la
reorganizacin, cuando se cree la tabla ATTRACTIONCATEGORY y AttractionCategoryId pase a ser clave fornea en
ATTRACTION y AttractionCategoryDescription inferido? Qu pasar con el registro pre-existente en ATTRACTION? Para
que la base de datos quede en estado consistente, tendr que crearse un registro en ATTRACTIONCATEGORY, con Id 1 y
con descripcin Nightlife. Esto lo har el propio programa de reorganizacin. Qu pasar si existan dos o ms atracciones
con el mismo Id de categora y distinta descripcin? Es lo que informa la advertencia. Investguelo.
74
Para que el usuario final no tenga que recordar cdigos para las claves forneas,
GeneXus crea objetos automticamente que se conocen como Prompts y que se
invocan mediante la imagen que aparece en ejecucin al lado de todo campo
clave fornea. Se trata de listas de seleccin que muestran toda la informacin de
la tabla referida, para que el usuario seleccione la deseada.
75
76
Para que el usuario final no tenga que estar abriendo estas listas de
seleccin cada vez que tenga que ingresar el valor de una clave fornea,
GeneXus provee de la facilidad de disfrazar en ejecucin un atributo por
otro. Mike propuso esto ltimo; Diego lo realiz cambiando dos propiedades
del atributo AttractionCategoryId, y como resultado, ahora para ingresar la
categora Buildings/Structures Mike slo debe recordar con qu letras
empieza, digitarlas y tendr autocomplete:
77
78
Captulo 3
79
Para
desplazamiento
entre las pginas
del grid
17
Ver pgina 32. Cuando se ingresan los atributos en la estructura de una transaccin, el primero de tipo Character o VarChar
ingresado, se marca como el descriptor. Se puede cambiar de descriptor posicionndose en la estructura sobre el nuevo atributo
descriptor, y va botn derecho- eligindolo mediante Toogle description attribute en el men contextual desplegado.
Aunque como veremos apenas ms adelante, Julia tendr otra alternativa para hacerlo
18
El valor por defecto es de 10 registros por pgina (es decir, carga 10 lneas del grid). Lo hemos modificado a 3 en un lugar
centralizado del Pattern Work With del que luego hablaremos.
80
19
El objeto Transaccin tiene una variable predefinida, &Mode, que identifica el modo en que se encuentra en un momento
dado (modo Insert, modo Update, modo Delete o modo Display) de acuerdo a la operacin que se vaya a realizar. Si se le enva
por parmetro el modo y se recibe en esta variable, entonces la transaccin sabr qu operacin se quiere realizar.
81
Patrones?
En lneas generales usted ya sabe de qu se habla cuando se dice patrn:
conocimiento comn que puede ser aplicado a situaciones distintas. Un pattern
en GeneXus es muy potente; evita que usted deba crear manualmente objetos
de gran versatilidad funcional; permite el reuso del conocimiento; y es un
utilitario abierto: llegado el caso, usted mismo puede crear sus propios
patrones. Introducen un alto nivel de productividad y generan aplicaciones de
calidad, con interfaces ms uniformes, y una lgica consistente. Es un
generador de conocimiento a partir de conocimiento.
82
Todo lo que Julia hizo fue aplicar el patrn Work With (uno de los
existentes) a la transaccin Country, obteniendo un trozo de aplicacin que
implementa todo lo necesario para poder Trabajar con la informacin
asociada, en nuestro caso: pases.
Podemos pensar al patrn Work With (as como muchos otros) como una
mquina, cuya entrada es una transaccin (y la KB) y cuya salida es un
conjunto de nuevos objetos GeneXus (algunos de los cuales mostramos antes
en ejecucin), ms cambios en algunas propiedades de la KB, ms la propia
transaccin modificada20
83
84
Configura el
web panel
WWCountry:
Configura el
web panel
ViewCountry
Esta imagen muestra una instancia del pattern Work With, la instancia
para Country, que permite personalizarlo21. Se puede observar una estructura
jerrquica conteniendo nodos y un conjunto de propiedades cuyos valores
determinarn la apariencia y el comportamiento de lo generado por el pattern
para esta instancia.
El pattern Work With generar, entre otras cosas, dos nuevos objetos
GeneXus, que pudimos ver en ejecucin, y que hemos incluido para usted sobre
la imagen de la instancia, de un tipo del que an no habamos hablado: Web
21
No hemos definido instancia. Puede pensarse como la declaracin de cmo se aplicar el patrn al caso particular de este
objeto.
85
En un caso tenemos un web panel que nos permite entre otras cosas listar los pases, filtrando por nombre, y en el otro
tenemos un web panel que nos muestra toda la informacin de un pas determinado y sus ciudades (stas en un grid dentro de
un tab).
23
Este web panel, WWCountry tiene su descripcin en singular Work With Country, sin embargo, en su pantalla se presenta
como Work With Countries. Por lo que para referirnos al mismo, utilizaremos indistintamente el singular y el plural, de
acuerdo a lo ms natural al contexto en el que lo estemos referenciando.
86
ese nodo, con <Supr>, el resto de los atributos, con la excepcin de CountryId.
Este ltimo no puede ser eliminado tan alegremente. Aunque no se le muestre
al usuario final en el grid, deber estar presente, invisible, como justificaremos
en breve. Por lo tanto, lo que har Julia en ese caso ser posicionarse sobre el
atributo en ese nodo, y, editando sus propiedades con <F4>, modificar la
propiedad Visible pasndola a False.
As quedar la instancia; vea la repercusin en ejecucin.
Requerimiento 1 listo!
El subnodo Orders indica el orden por el que en forma predeterminada se
desean recuperar los datos que se cargarn en el grid. El orden elegido por
defecto es (casualmente?) el de CountryName, el atributo descriptor. Los
usuarios pidieron poder elegir entre ese orden y uno por CountryWorldRegion,
as como uno compuesto por ambos.
Cmo puede el usuario decidir en ejecucin por cul criterio quiere
ordenar la informacin a recuperar? Mediante un combo box que le muestre las
posibilidades. Julia necesitar agregar los nuevos ordenamientos pedidos bajo
el subnodo Orders, a los que les dar un nombre (World Region, Both) que
87
sern las opciones que el usuario final ver en ejecucin en el combo insertado
automticamente por el pattern.
As quedar la instancia y luego el web panel generado (en ejecucin):
88
89
La forma que tiene todo objeto GeneXus de declarar los parmetros que recibe y
devuelve, es mediante la regla Parm.
Cuando desde el Work With Countries se elija un pas del grid para
modificarlo, se invocar a esta transaccin envindole el modo UPD que es
recibido en la variable &Mode y se enviar adems el CountryId
correspondiente (es por este motivo que tuvimos que dejarlo en el grid, oculto).
Cuando se quiere insertar, se enva INS y el valor vaco como segundo
parmetro, y as
90
26
COUNTRY slo tiene a COUNTRYCITY en esta relacin (muchas ciudades por cada pas) y por ello slo aparece un Tab.
Obsrvese que el nombre que eligi GeneXus para nombrarlo fue la descripcin del nivel 2 de la transaccin Country (la
descripcin de las lneas, que era City).
91
Ms?
Los usuarios, que por momentos parecen tener como especial misin en el
mundo encontrar las flaquezas de los desarrolladores y volver sus vidas
miserables, pidieron a Julia que luego de modificar un pas, no se volviera al
llamador, WWCountry, sino que les mostrara toda la informacin del pas
recin modificado (es decir, ir al View Country).
92
93
registros por pgina de los grids (cosa que ya habamos hecho sin mostrarle,
pasndola a 3), tenemos el nodo Grid27. Invitamos al lector interesado a
investigar sobre las configuraciones generales que puede realizar desde aqu.
Por ejemplo, puede cambiar el aspecto general de las pginas, los nombres de
las mismas, las imgenes para las acciones de Insert, Update, Delete y mucho
ms.
Reflexione el lector sobre lo que significa trabajar con. Qu otras cosas
podra pedir el infame usuario? (perdn lector, es que tambin somos
humanos). Pregntele a Julia y ella le podr contar que en esa misma reunin,
se le ocurri a esa especie particular de homo sapiens que quera:
A. Exportar la informacin de los pases con los que estaba trabajando, a una
planilla Excel. Puede usted creer? Adems dijeron que no queran:
B. Que se pudiera eliminar pases desde el Work With Countries. Y por si esto
no fuera poco, que queran:
y
C. Agregar otra accin ms sobre los pases (adems de las de Insert
Update ), cuyo efecto fuera mostrar en otra pantalla cada pas con sus
ciudades, todos juntos!, y en un formato ms agradable a la vista. (Un
poco ambiguo para nuestro gusto y el de Julia)
Julia disfrut con sorna: ante cada requerimiento que el usuario peda con
ojos maliciosos, haca un par de clics y listo. Salvo para el ltimo, donde el
usuario logr su aparente objetivo: complicarle la vida. Pero ni tanto. No
olvidemos que Julia no es tcnica, luego en la oficina pedira ayuda a Diego.
27
Si observa en su KB la propiedad Page del nodo Grid, encontrar que tiene el valor Page.Rows. Qu es Page? Pues un
dominio enumerado creado automticamente, que contiene un solo valor, Rows, cuyo valor por defecto es 10 y que nosotros
hemos cambiado a 3.
94
95
28
Como ver un poco ms adelante, a Diego no le resultar nada complicado ubicar esta nota de Julia entre toda la
documentacin que se supone desperdigada entre tantos objetos de la KB, y ser gracias a las Categoras Dinmicas, de las
que l mismo hablar en el captulo 6.
96
97
30
98
99
Pero espera habas dicho que tenamos tres caminos posibles para
implementar esto ltimo y slo me has explicado dos.
Qu suerte, Julia. Estaba esperando que te dieras cuenta. De hecho, el
tercer camino es el que yo hubiera utilizado desde un principio en este caso. Si
no lo hice fue para aprovechar a explicarte esto de las frmulas globales. Lo
que hicimos sera lo ms recomendable si creyramos que muchas veces, y en
lugares distintos, vamos a tener que realizar esa misma cuenta de las
atracciones. Pero si por el contrario, ser en pocos lugares, tal vez lo mejor
hubiese sido directamente definir la variable como antes en el nodo Attributes
de la instancia del Work With, por ejemplo &CountryTotalAttractions, y en la
propiedad LoadCode de la variable, especificar &CountryTotalAttractions =
count( AttractionName ).
Pero no es la misma frmula que antes?
S y no. Aqu no has definido un atributo frmula, sino que ests
utilizando la frmula localmente, como si fuera una funcin. Por el contexto en
el que est especificada -en nuestro caso estar en un grid que recorre la tabla
de pases- sabr que deber contar solamente las atracciones del pas que se
est cargando en cada caso.
As mostr a Julia, tras el <F5> cmo luce ahora el trabajar con pases:
100
32
N. de A. Frase latina, Quod Natura non dat, Salamantica non praestat para referir a que si la naturaleza no da inteligencia,
ni la prestigiosa Universidad de Salamanca puede darla.
101
102
103
- Observa que ahora aparece el grid de ciudades, junto con los atributos
CountryFlag y CountryName dentro de un rectngulo. Qu es? Otro tipo de
grid, uno llamado Free Style, pues como ves, la informacin del pas que
quieres listar se muestra no por columna, sino toda junta, con el diseo que t
decidas. Pero tambin es un grid. Mostrar por tanto, tantos pases como
existan en la tabla de pases. Observa que en sus propiedades aparece una
Columns, a la que modifiqu el valor de 1 a 3, y es por ello que puedes
ver en la imagen que le enviamos a los usuarios tres pases por fila. Rows 0
significa que no realice paginado, sino que muestre todos los pases
existentes. Luego observa que dentro del Free Style, podemos colocar
cualquier control, incluyendo otro grid. Y al hacerlo, GeneXus encuentra las
104
relaciones entre las tablas, y es por esta razn que est listando por cada pas,
sus ciudades en el grid, sin tener que indicarle nada, lo hace solo. Si no te
convence, mralo t misma en el listado de navegacin que aparece luego de
la especificacin, tras el <F5>. A ver si lo entiendes
105
ese pas, como una galera de imgenes que se deslizan. Quisiera hacer algo
que impresione qued pensativo.
- A los usuarios? Bueno, Diego, veo que hoy no ests para bromas.
Antes de que sigas, qued pendiente poder llamar desde el Work With
Countries a este web panel que acabas de implementar.
- Es verdad, pero eso sabes hacerlo. Simplemente debes agregar una
nueva accin a las ya predeterminadas (insert, update, etc.) en la instancia
del Work With de Country: la asociaremos a un botn fuera del grid y le
indicaremos que en esa accin queremos invocar al web panel
CitiesPerCountry que acabo de crear.
Sobre el nodo Selection (Work With Countries), con botn derecho,
seleccionar Add actions y luego posicionarse sobre el nuevo nodo Action y
otra vez repetir la operacin. Vea lo que hicieron nuestros amigos, y la
repercusin en ejecucin:
106
Requerimiento C listo!
107
108
109
110
111
112
doquier. Si abrimos este web panel, mira sus propiedades. Qu te dice esto?
113
114
Captulo 4
116
33
Recuerde que estamos simplificando la realidad: supondremos que no habr nunca ms de un aeropuerto por ciudad.
117
podramos
decir
que
los
atributos CountryId
y CityId en la
transaccin Flight
representan
una
ciudad de un pas,
pues se llaman igual que los identificadores de la transaccin Country. Es decir,
sern una clave fornea a la tabla COUNTRYCITY. Hasta all nada nuevo bajo
el sol, pero ahora debemos agregar otra ciudad34, en otro rol, el de ciudad de
destino. Es decir, tiene que aparecer una doble referencia a una ciudad: en un
caso en un rol de ciudad origen, y en el otro de ciudad destino. Cmo hacemos
esto? GeneXus no nos permitir agregar la misma pareja de atributos en la
misma transaccin, eso es obvio porque cmo se discriminara entre un
atributo y otro?! Pero podramos hacer algo as tom el lpiz y escribi dos
atributos nuevos, luego de lo cual antecedi a los dos primeros con la D de
departure y a los dos ltimos con A de arrival.
Hmm pero si GeneXus entiende que si se llaman distinto son otra
cosa ya no habra conexin entre vuelos y ciudades, verdad?...
Verdad. Solucin? Poder decirle a GeneXus que si bien se les ha
cambiado el nombre a los
atributos, por la necesidad
de diferenciarlos, de todos
modos corresponden al
mismo concepto. Es decir,
que no se confunda: que
por ms que el atributo
DCountryId no se llame
34
Cuando hablamos de ciudad, nos referimos a una ciudad real, como Pars. Para identificar una ciudad, necesariamente
debemos dar el par {CountryId, CityId}. Est sobreentendido. Por el diseo de las transacciones, una ciudad no tiene existencia
independiente del pas al que pertenece. As, existe ciudad Rosario de Argentina y ciudad Rosario de Uruguay. Pero no existe
Rosario, independiente del pas del que se trate.
118
CountryId, a todos los efectos es como si se llamase as, de modo que siga
estableciendo las relaciones de integridad referencial igual que antes. Decirle
esto a GeneXus es decirle que DCountryId es un subtipo de CountryId35. La
solucin completa, por tanto, es agrupar estas parejas en dos grupos de
subtipos, ves? inquira mientras rearmaba el croquis.
- Ah, comprendo! Gracias
a ello, DCountryId y
DCityId sern una clave
fornea en FLIGHT a la
tabla COUNTRYCITY, al
igual que ACountryId y
ACityId, verdad? Tienes dos claves forneas a la misma tabla.
As es, y se deben realizar todos
los controles de integridad referencial
automticamente contest al tiempo que
descubra un entusiasmo nuevo en Mary.
Podra luego quitarla del teclado?
De todos modos el problema no
se termin aqu continu Diego . En esta transaccin, adems de representar
que un vuelo tiene un pas-ciudad de origen y uno de destino, cosa que ya
hicimos, queremos poder inferir el nombre de cada pas y ciudad, para verlos
en el form. Es decir, queremos inferir para mostrar atributos que pertenecen a la
tabla extendida de FLIGHT, pero cmo los inferimos si tenemos una doble
referencia a la tabla?, es decir, no podemos poner directamente CityName,
porque de cul se tratara? Del atributo que se debe inferir de la clave fornea
{DCountryId, DCityId}, o del que se debe inferir de la otra clave fornea
{ACountryId, ACityId}? Hay una ambigedad!
Y bueno, le tendrs que cambiar el nombre tambin a esos atributos que
necesitas inferir (CountryName, CityName) y colocarlos en el grupo de
35
119
Obsrvese cmo Diego ha establecido el nombre de los subtipos respetando la nomenclatura GIK y comienzan con Flight,
el nombre de la transaccin, y continan con el nombre del grupo, Departure. De esta manera se asegura una semntica clara,
estableciendo el rol que juegan en la transaccin.
120
Slo con cambiarle el nombre a una de las dos ocurrencias de CountryId y de CityId alcanzara para eliminar la ambigedad.
121
Viendo que el atributo FlightClassType slo puede tener hasta tres posibles
valores fijos: Business, Standard y Executive, Diego cre un dominio
enumerado para l.
El atributo FlightDepartureTime almacena la hora del vuelo (no nos interesa la
fecha). Obsrvese su tipo de datos DateTime. De l, slo se utilizar la parte que
representa Time, por lo que en sus propiedades, modificaremos bajo el grupo
Picture la de nombre Date format. La pasaremos a None.
Antes y despus
Para mostrarle a Mary en ejecucin la nueva transaccin, hizo <F5> tras lo
cual tuvo que reorganizar la base de datos (tres nuevas tablas sern creadas).
122
123
Bueno, s, eso es lo que quieres, pero por eso mismo, all debers
colocar el atributo CountryName y no el subtipo, porque en verdad es as como
se llama el atributo en la tabla COUNTRY y no FlightDepartureCountryName.
As, Diego escribi CountryName en
la propiedad ItemDescriptions y
tambin modific el valor de la
propiedad ContextualTitle del atributo
FlightDepartureCountryName que ahora
dice Departure country. Hizo anlogas
acciones para FlightDepartureCityId,
para FlightArrivalCountryId y para
FlightArrivalCityId. Observe cmo luce
ahora el form, sin que Diego tocara nada
en l.
Hizo lo mismo para Airline, y
adems edit las propiedades del grid en
el form, modificando el valor de Rows,
pasndolo de 5 a 0. El valor de esta
propiedad especifica la cantidad de
lneas vacas que se presentan en
ejecucin para que el usuario ingrese los
datos all. Obsrvese que no es necesario
tener ninguna lnea vaca, dado que
abajo del grid aparece [New Row] para
agregar una lnea vaca al grid y poder llenarla.
Nuestro amigo hizo <F5> para mostrarle a Mary en ejecucin el despus:
124
125
count(FlightInstancePassengerSeatNumber)
Con este diseo, FlightNumber ser una clave fornea. Cuntos FlightInstance
podrn haber para el mismo vuelo, FlightNumber? Corresponde a lo deseado?
Existen algunos atributos aqu que merecen especial atencin. Por ejemplo,
FlightDepartureTime38 es la hora de partida estipulada del vuelo (es inferido de
FlightNumber), mientras que FlightInstanceDate y FlightInstanceTime son la
fecha y hora reales, del vuelo real. La hora del vuelo real, se inicializa en forma
predeterminada con el valor de FlightDepartureTime, pudiendo ser cambiada
por el usuario, para lo que Diego declar en las Rules:
default(FlightInstanceTime, FlightDepartureTime);
Esta regla slo se ejecuta cuando el modo es Insert. Por otro lado, observe
la otra regla que ha agregado Diego:
error('Number of passengers exceeded')
if FlightInstanceNumberOfPassengers > FlightTotalCapacity;
38
Si bien los atributos FlightDepartureTime y FlightInstanceTime son de tipo DateTime (permiten almacenar una fecha+hora),
slo nos interesa la representacin de la hora.
126
127
El siguiente Diagrama representa las relaciones entre las nuevas tablas y las
viejas.
Diego puls <F5>. Todo pareca bien, as que reorganiz la base de datos.
Luego accedi al Wiki, document la terminacin de esta etapa y dej a Mike
la tarea de probar lo hecho y a Julia la tarea de aplicar los Work With al resto de
las transacciones.
128
Captulo 5
Cuando el qu no alcanza
Slo declarar?... y las descripciones procedurales?
Fue lo que Mary cuestion un par de citas despus, en el bar de siempre. Se
haban estado viendo con mayor frecuencia, en su oficina o en el bar, lo que
haba dado oportunidad a intercambiar sobre varios asuntos, como patterns,
web panels y dems. Lleg a este nuevo encuentro, reflexiva. Deca entender
que las transacciones permiten de manera declarativa describir las visiones de
datos de los usuarios. Pero, es esto suficiente? Qu pasa con los procesos
batch o similares, que en toda aplicacin se necesitan? Estos procesos no se
pueden inferir a partir del conocimiento aportado por las visiones de datos.
Entonces?
S, faltara un lenguaje procedural, estamos de acuerdo ratific
Diego-. Si piensas en la filosofa de GeneXus, evidentemente deber ser un
lenguaje de muy alto nivel. Ms an: deber ser un lenguaje que no utilice
jams referencias al Modelo Relacional, sino slo al Externo. Te mostrar un
ejemplo tonto: suponte que necesitas, por la razn que fuere, por ejemplo por
malas condiciones en la pista de un determinado aeropuerto en un determinado
momento de un determinado da, posponer la hora de partida prevista de todos
los vuelos grandes (que sobrepasan determinada capacidad de pasajeros).
Suponte que debern atrasarse. En definitiva, debers acceder a todos los
registros de FLIGHTINSTANCE, tales que el valor de FlightInstanceDate y
FlightInstanceTime coincidan con la fecha y hora en la que no deben despegar
los aviones, y tales que correspondan a un vuelo que parta del pas y ciudad
determinado (aeropuerto) y que tenga una capacidad de pasajeros mayor que un
valor determinado. Para esos registros debes modificar el valor de
FlightInstanceTime, y eventualmente tambin el de FlightInstanceDate por los
nuevos. Podras hacerlo filtrando en el Work With FlightInstance por esos
129
130
donde las variables que aparecen fueron declaradas por Diego como
parmetros de entrada del procedimiento, en el selector Rules:
parm( in: &CurrentInstanceDate, in: &CurrentInstanceTime,
in: &CountryId, in: &CityId, in: &NewFlightInstanceDate,
in: &NewFlightInstanceTime, in: &FlightTotalCapacity);
Respire profundo, amigo lector, no se nos vaya a quedar sin aire a la mitad
131
valores de los primeros cuatro coincidan con los de las variables recibidas por
parmetro, y el valor de FlightTotalCapacity sea mayor o igual que el de la
variable tambin recibida por parmetro, cmbiale el valor que contengan
FlightInstanceDate y a FlightInstanceTime por los indicados.
Sigo sin entender. Esos atributos estn en tablas distintas.
FlightInstanceDate y FlightInstanceTime estn en FLIGHTINSTANCE, s,
pero los dems estn todos en FLIGHT No deberas recorrer?
Cierto interrumpi Diego sin dejarla terminar-. Pero FLIGHT est
en la tabla extendida de FLIGHTINSTANCE. Es decir, por cada vuelo real,
tienes un FlightNumber (clave fornea) que corresponde a un y solo un registro
de
FLIGHT,
que
tiene
un
FlightDepartureCountryId,
un
FlightDepartureCityId, y un FlightTotalCapacity. Hay una relacin N a 1 entre
FLIGHTINSTANCE y FLIGHT. Con eso no necesita ms: sabr que debe
recorrer la tabla FLIGHTINSTANCE, accediendo para cada registro a su
correspondiente en FLIGHT, es decir, haciendo un join automtico para saber
el valor de los atributos FlightDepartureCountryId, FlightDepartureCityId y
FlightTotalCapacity y con eso decidir si se queda o no con el registro para
procesarlo (por supuesto, siempre y cuando el propio registro de
FLIGHTINSTANCE cumpla con ser del da y hora indicados por las variables
&CurrentInstanceDate y &CurrentInstanceTime). La condicin que impone
sobre un registro para quedarse con l y procesarlo, es la concatenacin con
And de todas las condiciones lgicas que ves en las clusulas Where del For
each. Como antes hablamos de tabla base, aqu tambin: para el For each es la
tabla que recorre. Observa, entonces, cmo conociendo las relaciones entre las
tablas y dnde estn los atributos en el momento del anlisis, GeneXus puede
inferir el acceso a los datos sin que le tengas que nombrar tabla alguna. Esto
tiene una consecuencia importante: permite que se puedan cambiar de tabla
esos atributos, sin que la descripcin del procedimiento pierda validez40.
40
Por supuesto: siempre y cuando los atributos pertenezcan a una misma tabla extendida. En caso contrario GeneXus arrojar
un error, informando que no fue posible relacionar los atributos.
132
Tabla base
Ves? Te informa la tabla base del For each, el orden por el que
procesar la informacin41 y el ndice que propone para satisfacer ese orden (si
es que existe). Adems te informa los filtros de navegacin, es decir, desde
dnde empezar a recorrer la tabla y hasta dnde (en nuestro caso, recorrer
41
El orden puede indicarse mediante la clusula Order del comando For each. Como no se ha indicado, y no existe ningn
ndice en la base de datos que permita optimizar la bsqueda de los registros que cumplan estas condiciones, asume clave
primaria de la tabla a recorrer.
133
toda la tabla42). Luego se observan las Constraints (filtros sobre los registros a
recorrer). Ms abajo te informa que por cada registro de FLIGHTINSTANCE
deber hacerse un join con la tabla FLIGHT de su extendida (para realizar los
filtros
por
FlightDepartureCountryId,
FlightDepartureCityId
y
FlightTotalCapacity) y que se actualizarn de la tabla FLIGHTINSTANCE los
atributos FlightInstanceDate y FlightInstanceTime. S franca, Mary, y dime
cunto ms te costar implementar esto mismo utilizando las herramientas que
usas. Habras implementado t misma este join. Lo mejor de todo, en verdad,
es el hecho de seguir hablando en alto nivel. Piensa qu pasara en tu
implementacin, que seguramente requerir nombrar las tablas, si mueves por
ejemplo, el atributo FlightTotalCapacity de FLIGHT a FLIGHTINSTANCE.
Aqu no tendrs que tocar absolutamente nada. Simplemente volver a generar el
objeto, para que GeneXus infiera la nueva navegacin y listo!
S, comprendo. Y cmo insertas y eliminas registros de la base de
datos?
Bueno, el comando For each te permite recorrer una tabla de la base
de datos, y acceder a su extendida, tanto para consultar solamente, como para
actualizar atributos. Por este motivo, es un comando importantsimo, que podr
ser utilizado no slo en procedimientos sino en todo objeto GeneXus donde se
admita cdigo procedural (como los eventos de transacciones y web panels, por
ejemplo). Para las inserciones y eliminaciones se han creado dos comandos
especficos: New y Delete43.
42
134
135
Los Business Components se obtienen de objetos transaccin, pero pueden ser utilizados desde cualquier otro objeto
GeneXus, para hacer inserciones, eliminaciones y modificaciones en sus tablas.
45
Si la transaccin tiene 2 niveles, crear un business component por nivel.
136
137
138
139
Le tendr que decir a este procedimiento que tendr una salida como pdf.
La idea del Layout es declarar qu es lo que quiero mostrar en la salida.
Como resultado de la ejecucin, quiero mostrar para cada ciudad, todas sus
atracciones. Evidentemente, el usuario final tendr que tener Acrobat
Reader instalado para que desde el Browser se pueda abrir correctamente el
archivo pdf generado. Para indicar qu es lo que se quiere mostrar en la
salida y su formato, el Layout contiene reas de impresin, que son
controles llamados printblock. Coloreados en la imagen, puedes ver donde
empiezan dos de esos controles: City_Block y Attraction_Block. Esos
nombres se los di yo luego de insertar cada control. Dentro de cada
printblock insertas la informacin (atributos, variables, imgenes, lneas,
recuadros, etc.) que deseas desplegar en esa rea de datos, cuando sea
invocada desde el cdigo. Por ejemplo, observa que dentro de City_Block
he insertado los controles atributo CityId y CityName, porque esa es la
informacin de cada ciudad que querr mostrar en el listado.
Y slo con eso GeneXus ya sabe qu listar y cmo?
Mary, espera. El amigo no es mago, slo es inteligente. Con eso solo
no puede saber cmo quieres listar la informacin. Falta el cdigo dijo
enarcando las cejas, con expresin risuea, viendo aparecer un rubor...
140
Diego continu:
Observa que no necesitas establecer el filtro por ciudad para el
segundo For each: es que existe una relacin 1-N directa entre las tablas que se
recorren, siendo uno de los casos ms comunes de For eachs anidados. La tabla
base del For each externo es COUNTRYCITY, y la del interno es
ATTRACTION (por los atributos de los printblocks involucrados), y como
GeneXus conoce las relaciones entre las tablas, l implcitamente aplica la
141
142
143
144
Y las consultas?
Otro de los grandes alcances de GeneXus X es el objeto Query que permite
crear consultas a la base de datos, y mejorar la salida de la informacin
recuperada. sta puede ser visualizada en diferentes formatos (barras, tortas,
3D o planas, rea, etc.) lo que ayudar a enriquecer sus aplicaciones. Adems
permitir al usuario realizar consultas dinmicas (qu measure ver) a travs de
pivot tables, etc.
Una consulta de este tipo es definida como una estructura. Supongamos que
deseamos obtener una consulta de cantidad de despegues en una fecha dada
(FlightInstanceDate) por aerolnea (AirlineName) para cada ciudad
(CityName); en la siguiente imagen se resume esta intencin:
145
47
No todas las funciones de agregacin aplican para todos los tipos de atributos. Sum y Average estn solo disponibles para
atributos numricos.
146
147
148
Captulo 6
Ms declaraciones
Nuevos protagonistas del conocimiento: Data Providers
La meta de GeneXus: que usted declare, declare y declare. Cuando uno
declara dice el qu, y no se preocupa por el cmo, pues ste vara con el
tiempo. Con frecuencia se encuentran nuevas formas de implementacin,
mejores, ms eficientes. El qu es estable, la esencia. Conocimiento que
permite automatizar. Las transacciones y los business components eran, as, las
estrellas de GeneXus: declaraban la lgica del negocio. Declaraban
conocimiento. GeneXus encontraba, en cada etapa de su evolucin, un cmo.
Ahora, un nuevo protagonista irrumpe en escena: el Data Provider. Para una
gran variedad de casos, pasaremos de programar procedimientos, a declarar
data providers.
Qued usted intrigado? Mary tambin. Vea lo que pas.
Declarndose?
Sin responder a la pregunta que ella dejara sonando en el aire, Diego abre
torpemente su inbox de correo y encuentra un e-mail de la agencia donde le
solicitaban un nuevo requerimiento: deba generar un archivo de interfase con
formato XML para envirsela a cierta aerolnea donde figurara la cantidad de
plazas vendidas por vuelo de esa aerolnea, en cierta fecha.
Mira esto susurr a Mary girando la notebook para que ella leyera.
Fcil contest ella demorando en leer. Su vista se haba detenido
antes en otros mensajes de correo, y Diego lo percibi, pero no dijo nada.
Implementas un procedimiento parecido al que vimos. Pero cmo se hace en
GeneXus para generar la salida en formato XML? si bien pareca estar
149
150
151
152
153
154
Vio cmo los rojos labios de Mary se unan para pronunciar lo que adivin
ser un pero, aunque no lleg a saberlo, pues continu:
Espera, no he terminado. An no estoy filtrando por los parmetros
recibidos. Mira cmo completo el Data Provider:
156
157
158
159
160
Captulo 7
161
162
163
164
abro, vers que se trata de una lista, en rbol, de clases de controles (aunque no
slo).
No habamos hablado hasta el momento de exportacin/importacin en GeneXus. En este libro solamente diremos que se
pueden exportar objetos GeneXus y otro tipo de conocimiento de una KB en archivos de extensin xpz, que luego pueden ser
importados en otra o la misma KB. Para ello est la opcin del men Knowledge Manager.
166
Estrictamente hablando a la versin de la KB que est activa. Sobre versionado de KB, busque prximos episodios o en las
distintas fuentes de documentacin de GeneXus.
167
tome en cuenta que los objetos tendrn ahora este theme, observe cmo luce en
ejecucin. Por ejemplo, veamos el Work With Airline, y luego la transaccin
para modificar una aerolnea:
Los tipos de objeto Master Page y Theme son los que ms importan a la hora de
disear la esttica de la aplicacin.
168
169
Versionado de la KB?
El tiempo haca lo nico que sabe hacer; Mary y Diego parecan no percatarse
de ese avance inexorable.
Diego
S?
No crees que lleg el momento de se alis la falda con las manos,
y carraspe antes de continuar, segundos eternos para l-hacer una copia de
la KB?
Ah, copias de respaldo! Bueno, en realidad en GeneXus lo puedes
hacer muy muy muy fcilmente. De hecho, dentro de la misma KB puedes
contener fotografas de diversos estados de la misma en el tiempo. Y no solo
eso, puedes hacer desarrollos paralelos de distintas versiones. Por ejemplo,
quieres poner en produccin una versin, y continuar desarrollando nuevos
requerimientos, de tal manera que puedes ir luego haciendo correcciones a la
versin de produccin a medida que el usuario lo va requiriendo, que no
estorben el desarrollo principal.
Interesante, me lo cuentas luego? . Se levant del sof y parada
delante de l le ofreci extendida la palma de su mano-. Vienes?
170
171
172
173
174
aerolneas, pases, ciudades, vuelos, pasajeros, etc., slo podr ser efectuado
por empleados de la empresa, con permisos, a travs de la intranet), con otros
que pueden utilizarse en el front-end, es decir, en el sitio Web que ser
consultado por personas de todo el mundo va Internet.
Sin embargo, Diego, Mike y Julia han trajinado mucho ms de lo que
hemos podido apreciar. Han hecho la pgina principal de la Intranet,
modificando un poco la pgina Home creada por el pattern Work With. Han
agregado una seccin de login a la master page web panels con consultas
variadas y distintos mens.
Esa misma tarde, sin ir ms lejos, antes de la cita con Mary, mientras Paul
reciba un theme para modificar, Julia se contactaba con los usuarios de Travel
Agency y Mike terminaba los testeos. Diego observaba detenidamente cmo
haba quedado la pgina principal del sitio web de la empresa:
175
Final o principio?
Hasta aqu hemos obtenido distintas piezas de un rompecabezas que usted
ir armando, valindose de la ms importante: su imaginacin.
Con ella, las piezas faltantes se le irn descubriendo en una bsqueda
continua. Inacabable. El puzzle est siempre prximo a pero nunca se
completa. All radica su secreto: mantenernos eternamente en vilo, buscando,
pensando, imaginando, cambiando.
Amigos, con fe, con alegra, con generosidad, con la sinergia
de esta Comunidad, vamos adelante, y preservemos la magia.
Breogn Gonda en el cierre del XVI Encuentro Internacional GeneXus
20 de Setiembre de 2006
176
177