Tipos de DAtos Estructurados

Alcance

Objetos: Transactions, Work Panels, Web Panels, Procedures, Reports

Lenguajes: Java, .NET, Visual Basic

Interfaces: Web, Win

Introducción

El objeto GeneXus Structured Data Type (SDT), permite definir estructuras de datos. Estas representan, de una forma simple, datos cuya estructura está compuesta por varios elementos. Esto facilita y potencia la programación. 

Descripción

Los SDT tienen múltiples usos posibles:

-         facilitan el pasaje de parámetros (en particular permite proveer/consumir información estructurada en el uso de webservices)

-         simplifican la lectura y escritura automática de XML (con funciones de alto nivel),

-         permite mejorar la legibilidad del código,

-         permite el manejo de listas de largo variables de elementos.

Detallamos algunos de los posibles casos de uso.

 

Se podrán definir variables, en cualquier objeto, basados en un objeto estructurado (SDT) o una estructura definida en el.

 

En Edición el objeto tiene dos secciones

-         Estructura : aquí mediante un editor es posible definir la estructura del objeto.

-         Documentación : documentación del objeto.

Como todos los objetos GeneXus, también tiene asociado un conjunto de propiedades y métodos.

 

Estructura

La estructura puede ser multinivel, semejante a la de las transacciones, cada nivel puede tener uno o más elementos (o ítems). Podemos clasificarlos en elementos simples o elementos compuestos (por otros elemento).

Elementos  simples

En el diseño de un SDT, al definir un elemento, se debe especificar la propiedad Name que identifica al elemento, por lo tanto no pueden existir dos elementos  con el mismo nombre. La propiedad Data type  permite seleccionar entre los siguientes tipos de datos :

-         Tipos básicos de GeneXus (numérico, date, etc.)

-         Dominios

-         otro SDT ya definido.

 

La propiedad Collection indica si el elemento tiene o no múltiples instancias (puede repetirse). Tiene dos valores posibles, True o False

 

Elementos Compuestos

Se identifican con un bullet de color, en el editor, y son aquellos que definen un nuevo agrupamiento de elementos (una nueva colección o un agrupamiento de elementos simples).  

Tiene las mismas propiedades que los elementos simples, pero no se habilita la propiedad data type. Hay una excepción en el caso de un SDT que sea colección de tipo simple, ver caso de uso 2.3

 

Se habilita la propiedad Item Name solo cuando el elemento compuesto define  una Collection (propiedad Collection en True).Esta propiedad indica el nombre de cada uno de sus elementos. Este nombre, calificado por el nombre del SDT, será seleccionable como tipo de datos para la definición de variables, esto significa que se crearan dos tipos de datos uno con el “Name” (nombre del SDT)  y otro con Name.ItemName.

Documentación

Permite escribir un texto descriptivo del objeto.  

 

Propiedades del objeto

El objeto SDT tiene un Name que lo identifica. No es posible definir un objeto GeneXus con el mismo nombre del SDT. El formato es el mismo de los objetos GeneXus en cuanto a caracteres válidos para inicio, caracteres siguientes al primero válidos, cantidad de caracteres, etc.

Tiene un Description y un External Name. Este último es el nombre con el que se publica el tipo de datos en el WSDL, para el caso de Webservices. El valor por defecto es el de la propiedad Name.

La propiedad External Namespace es un string que representa el name space que aplica al External name (WSDL). El valor por defecto es el nombre del modelo sustituyendo los caracteres no válidos.

 

Operadores

NEW

Este operador retorna una nueva instancia inicializada, o sea una nueva  referencia al tipo de datos que se especifica. La sintáxis es:

 

          New SDTName()

 

SDTName es el nombre de un SDT o un ítem de una collection (cualquiera que pueda ser el tipo de datos de una variable). Por ejemplo

          A = New Client()  o

          ClientList.Add( New Client())

 

Desde la opción Insert/SDT (o con ctrl. + Space) es posible incluir un  estructurado.

Métodos

Cualquier SDT tiene los métodos que se describen a continuación.

ToXML

Retorna un string con el formato XML de los datos de la variable SDT.

Sintaxis: &a = &b.ToXml()

devuelve la representación XML del contenido de &b en la variable &a

 

El XML resultante tiene la siguiente estructura:

Por ejemplo con un estructurado de país:

el contenido del string resultado seria:

<Pais xmlns = “name_Kb”>

   <Nombre>Uruguay</Nombre>

   <Idioma>Español</Idioma>

   <Coordenadas>

        <Latitud>30</Latitud >

        <Longitud>35</Longitud>

   </Coordenadas>

   <Ciudades>

        <item> Montevideo </item>

        <item> Paysandú </item>

  </Ciudades>

FromXML

Es el opuesto del ToXML. recibe como parámetro un string que tiene una estructura XML desde la cual se carga el SDT.

Sintaxis: &b.FromXml( &a)

carga la estructura &b a partir del contenido de la variable &a.

Clone

Crea una nueva área de memoria y copia los datos de la variable en esta. Sintaxis:
   &var1  = &var2
.clone()  

Siempre debe estar asignado a una variable, la única excepción es dentro del comando Add

   &var1.add(var2.clone())

 

Método clone vs Operador New

El método Clone equivale a new de una variable y la asignación de cada item de la misma o sea:

Z = Y.clone()  è Z = New SDT()

                        z.a = y.a

                        z.b = y.b

Siendo a y b los elementos del estructurado SDT

 

Notar que la asignación Z = Y simplemente redirecciona ambas variables a la misma área de memoria y al modificar una estoy modificando la otra.

La ventaja del método clone, frente al new, es que realiza la copia automática de cada item del estructurado sin necesidad de hacer la asignación.

 

En el caso de subestructuras dentro del SDT (colecciones o no) no se crea una nueva instancia de ésta con el método clone (la copia es shallow), es necesario hacer un new o clone explicito por cada subestructura. En el caso de  subestructuras “definidas” dentro del SDT, que no sean colecciones no esta habilitado el método clone. Por ejemplo, con el SDT

Pais

Nombre    Char

Continente         

      Nombre   Char

 

  &Pais.Nombre = 'Uruguay' 

  &Pais.Continente.Nombre = 'América'
  &Paises.Add(&Pais.clone())

 

  &Pais.Nombre = 'Senegal'

  &Pais.Continente.Nombre = 'Africa'
  &Paises.Add(&Pais.clone())

 

En ambos países el continente es Africa. Para que cada registro tenga distinto continente se debe programar con el operador new.

Collections

Existen un conjunto de métodos y propiedades que solo aplican a colecciones de SDT. 

La propiedad Count retorna la cantidad de elementos de la colección. Es read only.

Los siguientes métodos solo aplican a SDT que sean colecciones :

Agrega Item en la posición relativa Position de la collection. Si se omite Position o se especifica “0”, se agrega el Item al final de la collection. Position comienza en 1.

Retorna una referencia al elemento con posición relativa Position en la collection. En caso de especificar posición (de un item de colección ) mayor a la ultima, el programa cancela.

No es válido asignar un valor con esta propiedad, por lo tanto no es correcto el código &sdt.item(&i) = Att, para cambiar un valor se debe remover (método remove) y agregar (método add) 

Elimina el elemento en la posición relativa Position de la collection y corre un lugar todas las posiciones.

Elimina todos los elementos de la collection.

Consideraciones

Definición de variables

Para cada SDT se define un tipo de datos y otro por cada uno de los Items de sus collections. Por ejemplo Si se define una colección de Ciudades, se define un tipo de datos Ciudades y otro Ciudades.Ciudad

Las variables cuyo tipo sea una SDT no pueden ser vectores o matrices.

Pasaje de Parámetros

No es posible referenciar variables de tipo SDT en:

 

Si bien no se controla, no es posible definir en la rule parm un item de una SDT, por ejemplo: Parm(&sdt.item)

Disparo de Rules

Se deben instanciar los elementos de una variable SDT, para poder disparar rules que dependen de dicha variable. Para esto se debe cumplir al menos una de las siguientes condiciones:

-         new en Evento Start o

-         parámetro de Trn o

-         parámetro en Call en el evento Start.

 

Asignación

La asignación de una variable de tipo Structure a otra del mismo tipo implica un incremento en la cantidad de referencias a la estructura. Hecha la asignación, una modificación a cualquier elemento de la estructura se verá reflejado en todas las variables que "apunten" a la estructura.

 

Por ejemplo en el código:

  &Pais.PaisNom = ‘Uruguay’

  …

  &PaisAux = &Pais

  …

  &PaisAux.PaisNom = ‘Brasil’

  &PaisNom = &Pais.PaisNom

 

La variable PaisNom tiene el valor ‘Brasil’, pues la dirección de la variable Pais y PaisAux es la misma luego de la asignación

Form

No es posible incluir un SDT en el form o printblock de un objeto, en ese caso ocurrirá un error de spec “spc0071: '%1 cannot be displayed or printed due to its data type (%2)”

Recorrida

Para recorrer una colección de elementos, es posible hacerlo con el comando for in array

 

For &pais in &paises

  &paisCod = &pais.Codigo

  &PaisNom = &pais.Nombre

  Load

Endfor

 

O con el comando do while:

 

Do while &I<= &Paises.Count

    &Pais =&Paises.Item(&I)

    ...

    &I=&I+1

Enddo

 

Integridad

No es posible eliminar un SDT que esta siendo utilizado por otro objeto.

Si es posible modificar la estructura de un SDT y por ejemplo eliminar un elemento del mismo, aunque este siendo referenciado por otro objeto.

Especificación y generación

No es posible especificarse/generarse directamente un SDT. La especificación/generación es implícita cuando se especifica un objeto que lo utiliza si el SDT cambió desde la última vez que fue especificado o se realiza una generación forzada.

Las variables definidas como estructuras son ignoradas si la especificación es para lenguajes que no las soportan (RPG, Cobol, etc.). Esto evitará errores de generación si las variables no son utilizadas (esta parte corre por cuenta del desarrollador).

 

Knowledge Manager

Si es posible exportar/consolidar un objeto SDT, al exportar un objeto que usa un SDT, se exportan automáticamente los SDT llamados.

 

Si se exporta un objeto que contiene variables que son estructuras, a un modelo que no contiene la definición de dichas estructuras aparecerá, al especificar, el mensaje: spc0056,   Internal error. Variable %1 definition is incorrect or not available. Data:%2.

 

En el diálogo de consolidación se agrega un nuevo valor “SDTs” a la opción “Do NOT overwrite”, esto permite sobrescribir o no las definiciones de los SDT de la knowledge Base consolidada.

 

Listados

Si es posible listar los objetos SDT desde List/Object, o ver el arbol de llamadas desde List/Browser

 

Webservices

Los Web Services normalmente retornan valores en estructuras de datos. Por ejemplo, retornan un "Cliente" que es una estructura que tiene "Codigo" y "Nombre" que a su vez es otra estructura que tiene "PrimerNombre", "SegundoNombre", etc.

 

Ahora es posible acceder a estos datos con variables de tipo "Cliente" y modificar/acceder a sus "miembros"

 

Al consumir un servicio, con el WSDL Inspector, en el caso de recibir datos complejos, este incluirá por lo tanto nuevas definiciones de SDT 

 

Recursividad

No son soportadas las definiciones recursivas. El Data type de una elemento de una estructura no puede ser el mismo que se esta definiendo.