Mostrando entradas con la etiqueta RPG. Mostrar todas las entradas
Mostrando entradas con la etiqueta RPG. Mostrar todas las entradas

lunes, 26 de enero de 2015

Lenguaje Binder.

En la entrada "Lenguaje Binder. Características y estrategias" anterior os presenté las características generales y estrategias en la creación de programas de servicio y el sentido de la signature. 
Ahora en esta entradas os explicaré los comandos del lenguaje binder. 

El código fuente binder se almacena en un miembro de un archivo de fuentes y el tipo de fuente es BND. En este fuente se almacenan las exportaciones de componentes que se incluirán en el programa de servicio cuando se compile. Este archivo no se compila; se utiliza en la creación del programa de servicio.


Creación de un programa de servicio

A la hora de crear un programa de servicio y en relación con las exportaciones que se incluirán en un programa de servicio existen dos posibilidades en el comando de creación (CRTSRVPGM):
  • Indicarle el miembro fuente donde está la definición de exportaciones a través del binder
Exportar . . . . . . . . . . . . EXPORT         *SRCFILE    
Exportar archivo fuente  . . . . SRCFILE        ArchivoFuente    
  Biblioteca . . . . . . . . . .                  Biblioteca
Exportar miembro fuente  . . . . SRCMBR         Miembro   
  • Indicarle que no existe miembro fuente y que recoja todas las exportaciones que están indicadas en el módulo o módulos que se van a enlazar en el programa de servicio.
Exportar . . . . . . . . . . . . EXPORT         *ALL_____    
Exportar archivo fuente  . . . . SRCFILE        ________    
  Biblioteca . . . . . . . . . .                  _________
Exportar miembro fuente  . . . . SRCMBR         ________



Personalmente utilizo la primera para poder tener control sobre las diferentes signatures que tenga y permita un programa de servicio. 


Binder. Definición de componentes exportables

Para facilitar la comprensión vamos a exponer un ejemplo sobre el que posteriormente crearemos el fuente Binder. Supongamos que tenemos un módulo que vamos a enlazar en un programa de servicio y en ese modulo tenemos tres componentes exportables (calcPrecio, calcDescuento, calcImpuesto) y un componente interno no exportable (convMoneda)

En el miembro Binder pondremos los componentes exportables de TODOS los módulos que compondrán el programa de servicio. Sobre el ejemplo anterior el miembro contendrá:

/*  Comentarios                                               */
/*                                                            */
          STRPGMEXP  PGMLVL(*CURRENT) LVLCHK(*YES)              
             EXPORT     SYMBOL(calcPrecio)                    
             EXPORT     SYMBOL(calcDescuento)                    
             EXPORT     SYMBOL(calcImpuesto)                    

          ENDPGMEXP                                             

Entre STRPGMEXP y ENDPGMEXP se podrán todos los componentes exportables bajo el código EXPORT.

STRPGMEXP tiene dos parametros. El primero (PGMLVL) lo veremos a continuación y el segundo LVLCHK(*YES) le indica al programa de servicio que cuando un ejecutable utilice este programa de servicio compruebe la Signature del programa de servicio con la que tiene almacenada el programa ejecutable y que se tomó en el momento de compilación. Esto sirve para que el SO entienda que no hay problema en utilizar el programa de servicio por el programa ejecutable que lo intenta utilizar.
Con /* */ podremos poner los comentarios que queramos.

Imaginemos que al compilar el programa de servicio SRVPGM1 con este binder, se genera una signature X1. 
Posteriormente se compilar dos programas PGM1 y PGM2 que se enlazan con ese programa de servicio por lo que en la definición de esos dos programas podremos comprobar que se enlazaron con la signature X1 del programa de servicio.


Binder. Añadir un nuevo componente

Aquí vamos a mostrar como añadir nuevos componentes SIN tener que recompilar todos los programas que ya están enlazados con el programa de servicio.

Supongamos que ahora en el módulo hemos añadido un componente exportable más (calcMargen). Tendremos que modificar el miembro binder y compilar el programa de servicio PERO lo que deseamos es que no tengamos que volver a compilar todos los programas que ya estaban utilizando ese programa de servicio. 
Eso lo facilita las signatures y el lenguaje Binder. Lo haremos de las siguiente forma:


          STRPGMEXP  PGMLVL(*CURRENT) LVLCHK(*YES)              
             EXPORT     SYMBOL(calcPrecio)                    
             EXPORT     SYMBOL(calcDescuento)                    
             EXPORT     SYMBOL(calcImpuesto)                    
             EXPORT     SYMBOL(calcMargen)                    

          ENDPGMEXP   

          STRPGMEXP  PGMLVL(*PRV) LVLCHK(*YES)              
             EXPORT     SYMBOL(calcPrecio)                    
             EXPORT     SYMBOL(calcDescuento)                    
             EXPORT     SYMBOL(calcImpuesto)                    

          ENDPGMEXP   

Sobre el contenido del miembro binder anterior hemos añadido un nuevo grupo de entradas y hemos modificado la entrada anterior poniendo *PRV. Este parámetro se refiere únicamente a que es una versión anterior (puede haber tantas como versiones haya tenido el programa de servicio) y *CURRENT identifica la versión actual.

En las lineas antiguas cambiaremos *CURRENT por *PRV y crearemos un nuevo conjunto con la expresión *CURRENT y que contenga todos los componentes anteriores más los que hayamos añadido nuevos (calcMargen). Es necesario que los nuevos componentes se añadan al final para que no haya que recompilar todos los programas que enlazaron la versión anterior del programa de servicio.

Siguiendo con el ejemplo, al compilar el programa de servicio SRVPGM1 tendremos que tiene la signature X2 y X1 (la anterior).
Los programas antiguos PGM1 y PGM2 que tenían la signature X1 siguen funcionando correctamente sin tener que volver a compilarlo.
Ahora se compila un nuevo programa PGM3 y en este caso al enlazarlo al programa de servicio, recogerá la signature X2 del programa de servicio.  
Y todos los programas funcionan perfectamente!!!!!


Es la gran ventaja de los programas de servicio. Podremos añadir funcionalidades nuevas (y hacer determinados cambios) que hacen que todos los programas que los utilizan no haya que recompilarlo... (lógicamente teniendo un poquito de cuidado con el orden de componente exportables y con los parámetros de los componentes exportables).

Binder. Eliminar un componentes exportables sin recompilar programas

Aquí vamos a mostrar como eliminar un componentes SIN tener que recompilar todos los programas que ya están enlazados con el programa de servicio. No sería la mejor opción pero podría ser útil en el caso de que tengamos un programa de servicio con muchísimos programas que lo utilicen y no queramos (o no podamos) compilarlos.

El objetivo es que no cambien las signatures. Para ello, simplemente dejaremos el componente (con sus parámetros de entrada y salida) pero le "limpiaremos" el código, es decir, no hará nada. Aún así, se supone que no hay ningún programa que utilice ese componente. En el fuente binder dejaremos el componente en la misma posición. De esta forma al no eliminar el componente, no se cambiarán las signatures.










miércoles, 26 de junio de 2013

Lenguaje Binder. Características y estrategias.

Los programas de servicio (*SRVPGM) se crearon en ILE para encapsular funciones reutilizables y cuya gran ventaja es que en tiempo de ejecución es rendimiento es muy bueno debido en parte a que cuando se crea un programa, se guarda cierta información del programa de servicio que facilita la carga e inicialización del mismo. Es la signature.
Podéis tener una información más detallada de las formas de llamada a objetos en ILE sobre este enlace.


Signature.

Pero ¿qué es esto?. De forma burda, se puede comparar con el lvlchk de un fichero. En este caso si un programa se ha creado utilizando un determinado lvlchk de un fichero, en el momento en que se vaya a utilizar dicho fichero en tiempo de ejecución, el sistema operativo comprobará que es el mismo, en cuyo caso permitirá continuar con la ejecución pero en caso contrario dará un error y finalizará el programa.

La signature es similar. Cuando se crea un programa ILE y se enlazan los programas de servicio, se almacena en el programas la signature del programa de servicio. En tiempo de ejecución, cuando se llama al programa, en tiempo de inicialización, revisa que la signature almacenada en el programa es igual a la que tiene el programa de servicio y si es así, permitirá la ejecución del programa y en caso contrario dará error.

Una diferencia muy importante con respecto al lvlchk de un fichero y que nos facilitará el mantenimiento de aplicaciones es que un programa de servicio puede tener muchas signatures que serían como versiones del mismo programa se servicio. 
Así, si por ejemplo tenemos, un programa de servicio con las signatures 1 y 2 y lo llaman dos programas, el programa X que cuando se creo lo enlazaba con la signature 1 y el programa Y que cuando se creo lo enlazaba con la signature 2, pueden funcionar perfectamente.



Ejemplo de múltiples signatures válidas de un programa de servicios. Comando DspSrvPgm


Como se genera y en que se basa

Hay dos formas de crear la signature. De forma automática o de forma manual. 
  • En la automática es el sistema operativo quien crea la signature en el momento de creación de programa de servicio.
  • En la forma manual es la persona que crea el programa de servicio quien le da el código que desea.
 Yo, hasta el momento, siempre he utilizado la forma automática ya que la ventaja principal que le encuentro es que es el SO quien controla el código que debe asignarle. En la forma manual es el usuario quien debe controlar el código o códigos que se le da y sería un trabajo más a realizar y con la posibilidad de generar errores cuando un programa de servicio pudiera tener varias signatures.

Pero en ¿qué se basa el código que le genera?

Esto tiene que ver con la reducción del tiempo de inicialización del programa de servicio en tiempo de ejecución. Para ello, se pretende que en tiempo de compilación ya que pueda revisar que esa llamada sea correcta. Y para ello inventaron la signature. 
Por ello, el código que genera está basado en:

  • Los componentes exportables que tienen un programa de servicio
  • El orden de los componentes exportables
  • Los parámetros de entrada y salida de cada componente exportable. 

Por lo tanto, como se ve, ese código que genera le permite al sistema operativo realizar una revisión muy rápida en tiempo de ejecución de si va a "casar" las llamadas al programa de servicio dentro del programa que estoy ejecutando.

Por ello es muy importante indicar que si cambio el código "interno" de un componente de un programa de servicio (sin tocar los parámetros de entrada/salida), la signature NO cambiará. 


Entendido, pero ¿cómo facilitan el mantenimiento de aplicaciones?

Hemos comentado que los programas de servicio permiten reutilizar código, realizar funciones comunes y me facilitan el mantenimiento de aplicaciones pero con la gestión de la signature ¿cómo puedo hacerlo fácilmente?

Vamos a ver con un ejemplo todas las posibilidades. Imaginemos que tenemos:

  • Un programa de servicio llamado SRV1 que tiene un componente exportable llamado calcDescuento. Este componente tiene un parámetro de entrada Importe y un parámetro de salida que es Descuento (como función). Básicamente lo que hace es recibir un importe y base a una serie de criterios, calcula un descuento que lo devuelve al programa que lo llamó. Los criterios son:
    • Si el importe es menor o igual que 1000 el descuento es un 0%
    • Si el importe está entre 1000 y 5000 el descuento es de un 10%
    • Si el importe es mayor que 5000 el descuento será de un 20%
  • Este componente del programa de servicio es utilizado 120 en los programas
 *==============================================
 *  calcDescuento    Calcula descuento          
 *==============================================
PcalcDescuento    B                   EXPORT    
DcalcDescuento    PI     15      4              
D P_Importe              15      4    Const     
                                                
D w_Descuento     S      15      4              
 /Free                                          
    // Aqui vendra el codigo del componente     
                                                
    Return w_Descuento                          
 /End-Free                                      
P                 E                             



1. Solo cambia el código interno

Ahora la Dirección indica que los criterios de descuento han cambiado y hay que aplicarle los nuevos que son:
  • Si el importe es menor o igual que 1000 el descuento es un 0%
  • Si el importe está entre 1000 y 2000 el descuento es de un 10%
  • Si el importe es mayor que 2000 el descuento será de un 20%
En este caso, modificaré el componente calcDescuento, compilaré el programa de servicio SRV1. 
NO cambia la signature del programa de servicio y NO es necesario compilar el resto de programa para que tome el nuevo funcionamiento.


2. Se cambian los parámetros de un componente.

Ahora, por evolución del negocio, se ha pedido que al componente calculoDescuento se incluya un parámetro que sea un indicador de si tiene derecho a un descuento especial
 adicional. Además, la posibilidad de utilizar este descuento sólo estará habilitada en unos pocos de los actuales programas que utilizan el programa de servicio.

La forma de proceder para evitar tener que volver a crear todos los programas que utilizan ese componente sería la siguiente:

  • En el componente calcDescuento se añade el nuevo parámetro pero con opción *NOPASS. De esta forma, no será necesario modificar todas las llamadas de todos los programas que utilicen ese componente si no sólo los programas donde tenga sentido utilizar ese componente.
  • En las líneas de código de este componente, lo primero será determinar si ese parámetro viene "relleno". En caso de que venga, se tomará el valor que se recibe y en caso contrario se tomará el valor por defecto, en este caso, que no tiene derecho a descuento especial.
De esta forma, se creará de nuevo el programa de servicio y no será necesario crear todos los programas que lo utilicen. Solo se deberán crear aquellos donde se quiera utilizar el nuevo parámetro.

PcalcDescuento    B                   EXPORT                           
DcalcDescuento    PI     15      4                                     
D P_Importe              15      4    Const                            
D P_DescEspecial                  n   Const OPTIONS(*NOPASS)           
                                                                       
D w_Descuento     S      15      4                                     
D w_DescEspecial  S               n                                    
 /Free                                                                 
    If %PARMS >=2;                                                     
      w_DescEspecial = P_DescEspecial;                                 
    Else;                                                              
      w_DescEspecial = *Off;                                           
    EndIf;                                                             
    // Aqui vendra el codigo del componente y opera 
    // con w_DescEspecial 
                                                                       
    Return w_Descuento                                                 
 /End-Free                                                             

P                 E                                                    


3. Se añade un nuevo componente al programa de servicio.

Ahora, por necesidades de algunos programas, se ha creado un nuevo componente calcImpuesto que se ha incluido en el mismo programa de servicio y será utilizado sólo por unos pocos programas.

En este caso, si NO utilizamos el lenguaje binder, al crear el programa de servicio, cambiará la signature y estaremos obligados a volver a crear TODOS los programas enlazando de nuevo con el programa de servicio.

Si utilizamos el lenguajes binder podremos evitar tener que compilar todos los programas. Añadiremos una nueva entrada para que genere una nueva signature y con el ello, cuando se cree  el programa de servicio, será válido para todas las signatures previas y por lo tanto NO será necesario volver a crear los programas que lo utilizan.


En próximas entregas, indicaré como se codifica el lenguaje binder para el mantenimiento de programas de servicio en base a estas características.



jueves, 23 de mayo de 2013

Modulo. Mantenimiento de un registro



Objetivo

Realizar un módulo que presenta una ventana para el mantenimiento de los datos de un registro. Permitirá dar de alta un nuevo registro o realizar las opciones de modificación, consulta o borrado de un registro existente. Lógicamente validará la información introducida por el usuario antes de actualizar la información en la base de datos.
Para los campos de tipo tabla también se habilita el acceso a los programas de lista de selección (F4) en el ejemplo que se mostrará sobre el campo de país y de tipo de cliente.
En este ejemplo, se realizará una pantalla de mantenimiento de un cliente. Será llamado desde la pantalla de lista de clientes.





Tiene el mandato F10 para confirmar  la acción de alta, modificación o borrado. Con F4 accederá a la lista de selección de país y de tipo de cliente. Con F12 no realizará ninguna acción y volverá a la pantalla que le llamó.

Referencias: ILE estrategiaBD Pruebas

Configuración

Este programa utilizará un componente de acceso a base de datos de lista de clientes, los componentes de actualización (alta, baja y modificación) de un registro y los componentes de validación que se encuentran todos ellos en el programa de servicio correspondiente.
  • El nombre del módulo donde esta el ventana de lista de registros para mantenimiento BAN02P1
    • La definición de la pantalla estará definida como BAN02S1
  • Utiliza el programa de servicio BAN01SRV que contiene los componentes de acceso a BD, de actualización y de validación
    • El miembro (/Copy) con la definición del prototipo con los componentes y con la definición de estructuras será BAN01M1CP
  • Llamará a los programas de lista de países (PAN40P1) y lista de tipos de cliente (PAN40P2) 
    Este ejemplo sirve de plantilla para otro proceso similar.


    Fuente de la pantalla. BAN02S1

    Se define la pantalla para presentar el mantenimiento de un registro.

    miércoles, 22 de mayo de 2013

    Modulo. Lista para mantenimiento


    Objetivo


    Realizar un módulo que presenta una ventana con una lista de registros que servirá para el mantenimiento de los mismo. Tendrá opciones para acceder a la pantalla que permite dar de alta un nuevo registro o realizar las opciones de modificación, consulta o borrado de un registro existente. Además incorpora una búsqueda para seleccionar los registros que aparecen en la lista. La lista se cargará por páginas.
    Para los campos de tipo tabla también se habilita el acceso a los programas de lista de selección (F4) en el ejemplo que se mostrará sobre el campo de país y de tipo de cliente.
    En este ejemplo, se realizará una pantalla de lista de registros para mantenimiento para la tabla de clientes.




    Tiene el mandato F9 para dar de alta un nuevo registro. Las opciones sobre el subfichero 2, 4, 5 para realizar las opciones de mantenimiento de modificación, borrado y consulta respectivamente. 
    Tiene en la cabecera los campos de búsqueda para restringir la información que se muestra en la lista.
    Adicionalmente he añadido una opción (8) en el subfichero para acceder a la lista de cuentas del cliente que será otra pantalla similar a esta y que utilizará la misma plantilla con el punto adicional que se presenta información del cliente al que pertenece (maestro-detalle)

    Referencias: ILE estrategiaBD Pruebas

    Configuración

    Este programa utilizará un componente de acceso a base de datos de lista de clientes que se definió en la entrada de acceso a BD a través del uso del programa de servicio que lo contiene .
    • El nombre del módulo donde esta el ventana de lista de registros para mantenimiento BAN01P1
      • La definición de la pantalla estará definida como BAN01S1
    • Utiliza el programa de servicio BAN01SRV que contiene los componentes de acceso a BD.
      • El miembro (/Copy) con la definición del prototipo con los componentes y con la definición de estructuras será BAN01M1CP
    • Llamará a los módulos de mantenimiento de un registro de cliente (PAN02P1) y a la lista de cuentas asociadas a un cliente (PAN03P1)
    • Llamará a los programas de lista de países (PAN40P1) y lista de tipos de cliente (PAN40P2) 
    Este ejemplo sirve de plantilla para otro proceso similar.


    Fuente de la pantalla. BAN01S1

    Se define la pantalla para presentar la lista de registros para mantenimiento.

    lunes, 20 de mayo de 2013

    Modulo. Lista de seleccion (F4)

    Continuando con la serie de entradas relacionadas con el tema de la estrategia de desarrollo en ILE presento una plantilla de programa de selección de un registro.

    Objetivo


    Realizar un programa que presenta una ventana de selección (típica consulta de F4 en formato window) donde se podrá un registro para devolver al programa que le ha llamado.
    En este ejemplo, se realizará una ventana de selección de países.

    Referencias: ILE estrategiaBD Pruebas


    Configuración 

    Este programa utilizará un componente de acceso a base de datos de lista de países similar al que se definió en la entrada de acceso a BD a través del uso del programa de servicio que lo contiene .
    • El nombre del módulo donde esta el ventana de lista de selección BAN40P1
      • La definición de la pantalla estará definida como BAN40S1
    • Utiliza el programa de servicio BAN01SRV que contiene los componentes de acceso a BD.
      • El miembro (/Copy) con la definición del prototipo con los componentes y con la definición de estructuras será BAN01M1CP
    Este ejemplo sirve de plantilla para otro proceso similar.


    Fuente de la pantalla. BAN40S1

    Se define la pantalla para presentar la lista de registro y para seleccionar un registro.



    A                                      DSPSIZ(24 80 *DS3)
    A                                      PRINT
    A          R BAN40S01                  SFL
    A                                      SFLNXTCHG
    A            S_OPCION       1A  B  8  4VALUES(' ' '1')
    A            S_DSPAIS      35A  O  8 12
    A            S_IDPAIS       3A  O  8  8
    A          R BAN40C01                  SFLCTL(BAN40S01)
    A                                      CF03(03 'Salir')
    A                                      RTNCSRLOC(*RECNAME &REGCUR &CAMCUR)
    A                                      OVERLAY
    A                                      SFLCSRRRN(&CURS01)
    A  40N41                               SFLDSP
    A N41                                  SFLDSPCTL
    A  41                                  SFLCLR
    A  40N41                               SFLEND(*MORE)
    A                                      SFLSIZ(0010)
    A                                      SFLPAG(0009)
    A  61                                  SFLMSG('Solo se puede seleccionar u-
    A                                      n registro' 61)
    A                                      WINDOW(BAN40P01)
    A            CURS01         5S 0H
    A            NRR            4S 0H      SFLRCDNBR(CURSOR)
    A            CAMCUR        10A  H
    A            REGCUR        10A  H
    A            WKSTNS        10A  O  1 30DSPATR(HI)
    A                                  2  3DATE
    A                                      EDTCDE(Y)
    A                                      DSPATR(HI)
    A                                  2 40USER
    A                                      DSPATR(HI)
    A            D_DSPAIS      25A  B  4 10DSPATR(HI)
    A                                  4  4'Pais'
    A                                  7  3'Opc'
    A                                      DSPATR(HI)
    A                                      DSPATR(UL)
    A                                  7  8'Pais'
    A                                      DSPATR(HI)
    A                                      DSPATR(UL)
    A                                  5  4'1-Seleccionar'
    A                                  1 18'Lista de paises'
    A                                      DSPATR(HI)
    A                                  1  3'BAN40P1'
    A                                      DSPATR(HI)
    A          R BAN40P01
    A                                      WINDOW(2 15 20 50)
    A                                      WDWBORDER((*DSPATR RI) (*CHAR '    -
    A                                          '))
    A                                 18  5'F3-Salir'
    A          R BAN40R00
    A                                      KEEP
    A                                      ASSUME
    A                                  5  3' ' 


    Se define:

    domingo, 19 de mayo de 2013

    Cgidev2

    Hola de nuevo. Voy a dejar un momento el tema de ILE que estaba tratando en entradas previas y os voy a presentar Cgidev2. En cualquier caso, la misma estrategia que os estaba presentando para 5250 la utilizo para el desarrollo con Cgidev2 y me sirve para reutilizar todos los componentes que puedo :)

    CGIDEV2 es una herramienta Open Source que permite comunicar con un navegador web desde un programa Rpg o Cobol. Por lo tanto permite "crear" páginas web desde estos lenguajes.
    En si es un programa de servicio con un conjunto de componentes que encapsulan APIs del sistema operativo y que permiten procesar protocolo http. Con ellos, desde RPG, podemos "leer" un formulario rellenado en una página web y podremos crear un página web de respuesta.

    Podrás acceder a la página principal de Cgidev2 y donde encontrarás todo tipo de  documentación a través de este enlace.


    En esta entrada definiré un programa sencillo que permitirá obtener una lista de clientes de un fichero. Muestro una imagen de la salida en un navegador web.

    Pruebalo aquí. Ahora prueba poniendo sustituyendo el 0 final en la url por un 1. 

    Instalación


    De la página de Cgidev2 es necesario descargarse la herramienta y las instrucciones de instalación. La instalación creará una biblioteca llamada Cgidev2 con los objetos y el programa de servicio y generará una instancia del servidor web Apache. El servidor web es el que servirá para comunicar entre el navegador web y los programas RPG. 

    Que es necesario

    En un proceso "normal" del iseries cuya salida es 5250, es necesario, para interactuar con el usuario, un fichero de pantalla Dspf y un programa Rpg. 
    Para el entorno web utilizando esta herramienta, es necesario disponer de una plantilla Html y un programa Rpg que además utilice el programa de servicio Cgidev2

    Html es un lenguaje de texto y basado en "marcas" y es son capaces de interpretar los navegadores web para presentar una pantalla. Es sencillo y podéis encontrar ayuda en muchas webs como por ejemplo 3schools.

    Plantilla html

    Es un archivo Html PERO donde se han incluido algunos tags que será interpretados por Cgidev2 en su ejecución. Por lo tanto NO es un html puro. Lo que contiene son definición de secciones (parecido a un formato de registro de un informe Rlu) y variables que se sustituirán en tiempo de ejecución por lo valores asociados. 
    Anexo la plantilla html que ha generado la pantalla.


    miércoles, 15 de mayo de 2013

    Componente. Validación



    Objetivo


    Crear componentes  que sean capaces de validar determinada información. 
    En este ejemplo, se realizará un componente para validar varios campos.

    Referencias: ILE estrategiaBD Pruebas

    Estos componentes complementan al componente acceso de datos y de actualización de base de datos presentado en entradas anteriores.

    Configuración

    Se utiliza SQL para el desarrollo del código. El componente  formará parte de un programa de servicio y será exportable por lo que podrá ser llamado por el programa que enlace este programa de servicio.
    • Los nombres de los componentes (Val_Nombre, Val_IdPais). Utilizo siempre Val_xxxxxx donde xxxxx es el nombre del campo a validar.
    • El nombre del módulo donde estarán los componentes BAN01M1
    • El miembro (/Copy) con la definición del prototipo con los componentes y con la definición de estructuras será BAN01M1CP
    • El programa de servicio donde estarán los módulos BAN01SRV. Tendrá un miembro asociado con el mismo nombre con la definición (binder) de los componentes a exportar.

    Miembro /Copy. BAN01M1CP

    Se describen las estructuras de datos que dan servicio al componente de acceso a base de datos y el prototipo de llamada. Estarán en un miembro fuente independiente para que sea utilizado como /Copy tanto por el fuente del componente como los fuentes de los posibles programas que lo utilicen.


     *==========================================================
     *    Validar Campo de Nombre de cliente
     *       E01 - No permite blancos
     *==========================================================
    DVal_Nombre       PR              n
    D P_Nombre                      50    Const
    D P_IdError                      3

     *==========================================================
     *    Validar Campo de Pais
     *       E01 - No permite blancos
     *       E02 - Pais no existe
     *==========================================================
    DVal_IdPais       PR              n
    D P_IdPais                       3    Const
    D P_IdError                      3          



    Está compuesto por:
    • (Val_Nombre) Definición de prototipo (interfaz) para validar el campo de nombre del fichero de clientes.
    • (Val_IdPais) Definición de prototipo (interfaz) para validar el campo de Id de Pais del fichero de clientes.

    Al principio del fuente del componente se utiliza el /COPY para “cargar” las estructuras de datos y los prototipos de los componentes. 

    /COPY *LIBL/QRPGLESRC,BAN01M1CP

    Fuente del componente. Val_Nombre en BAN01M1

    Este componente valida que sea correcto el contenido del campo nombre que pertenece al fichero de clientes

    El componente tiene el siguiente código:

    martes, 14 de mayo de 2013

    Componente. Actualización de base de datos


    Objetivo


    Crear un componente que sea capaz de añadir, actualizar o borrar un registro de una entidad de una base de datos. 
    En este ejemplo, se realizará un componente para actualizar información de la tabla de clientes.


    Estos componentes complementan al componente acceso de datos presentado en entradas anteriores.

    Configuración

    Se utiliza SQL para el desarrollo del código. El componente  formará parte de un programa de servicio y será exportable por lo que podrá ser llamado por el programa que enlace este programa de servicio.
    • Los nombres de los componentes (Add_Cliente, Upd_Cliente, Dlt_Cliente). Utilizo siempre Add_xxxxxx, Upd_xxxxx, Dlt_xxxxx donde xxxxx es la entidad para la definición del componente de actualización.
    • El nombre del módulo donde estarán los componentes BAN01M1
    • El miembro (/Copy) con la definición del prototipo con los componentes y con la definición de estructuras será BAN01M1CP
    • El programa de servicio donde estarán los módulos BAN01SRV. Tendrá un miembro asociado con el mismo nombre con la definición (binder) de los componentes a exportar.

    Miembro /Copy. BAN01M1CP

    Se describen las estructuras de datos que dan servicio al componente de acceso a base de datos y el prototipo de llamada. Estarán en un miembro fuente independiente para que sea utilizado como /Copy tanto por el fuente del componente como los fuentes de los posibles programas que lo utilicen.


     *===========================================================
     ** Alta de cliente
     *===========================================================
    DDs_AddClie       DS                  QUALIFIED
    D Nombre                        50
    D Apellidos                    100
    D Direccion                    100
    D IdPais                         3
    D IdTipCli                       1

    DAdd_Cliente      PR            10  0
    D P_DsClieAlt                         Const LikeDs(Ds_AddClie)

     *============================================================
     ** Actualizacion de cliente
     *============================================================
    DDs_UpdClie       DS                  QUALIFIED
    D Nombre                        50
    D Apellidos                    100
    D Direccion                    100
    D IdPais                         3
    D IdTipCli                       1

    DUpd_Cliente      PR
    D P_IdCliente                   10  0 Const
    D P_DsClieMod                         Const LikeDs(Ds_UpdClie)

     *============================================================
     ** Borrado de cliente
     *============================================================
    DDlt_Cliente      PR
    D P_IdCliente                   10  0 Const


    Está compuesto por:
    • (Ds_AddClie) y (Ds_UpdClie)  Estructura de datos con los campos para generar un cliente y para actualizar un cliente respestivamente.
    • (Add_Cliente) Definición de prototipo (interfaz) para generar un nuevo cliente.
    • (Upd_Cliente) Definición de prototipo (interfaz) para actualizar los datos de un cliente
    • (Dlt_Cliente) Definición de prototipo (interfaz) para generar un nuevo cliente.

    Al principio del fuente del componente se utiliza el /COPY para “cargar” las estructuras de datos y los prototipos de los componentes. 

    /COPY *LIBL/QRPGLESRC,BAN01M1CP

    Fuente del componente. Add_Cliente en BAN01M1

    Este componente genera un nuevo cliente en la tabla correspondiente y devuelve el id de cliente (clave primaria) que ha generado


    El componente tiene el siguiente código:

    lunes, 13 de mayo de 2013

    Componente. Acceso a BD

    Objetivo


    Crear un componente que sea capaz de devolver un registro o una lista de registros de una o varias entidades de una base de datos. Debe permitir que se pueda seleccionar un filtro de datos y también indicar la ordenación que se desea. Además debe ser posible indicar que se devuelvan los registros de una determinada página, es decir, desde una determinada posición y un número determinado de registros.
    En este ejemplo, se realizará un componente para obtener información de la tabla de clientes.




    Configuración

    Se utiliza SQL para el desarrollo del código. El componente  formará parte de un programa de servicio y será exportable por lo que podrá ser llamado por el programa que enlace este programa de servicio.
    • El nombre de componente (Obt_LstClientes). Utilizo siempre Obt_Lstxxxxxx donde xxxxx es la entidad para la definición del componente de acceso a base de datos para recuperar una  lista de registros.
    • El nombre del módulo donde estarán los componentes BAN01M1
      Tendrá los siguientes componentes:
      • (Obt_LstClientes) para recuperar la lista de clientes. Exportable
      • (Obt_LstCuentas) para recuperar la lista de cuentas. Exportable
      • (Sentencia_Ini) para inicializar el cursor de la ejecución de la sentencia. INTERNO.
      • (Sentencia_Fin) para finalizar el cursor de la ejecución de la sentencia. INTERNO.
    • El miembro (/Copy) con la definición del prototipo con los componentes y con la definición de estructuras será BAN01M1CP
    • El programa de servicio donde estarán los módulos BAN01SRV. Tendrá un miembro asociado con el mismo nombre con la definición (binder) de los componentes a exportar.

    Miembro /Copy. BAN01M1CP

    Se describen las estructuras de datos que dan servicio al componente de acceso a base de datos y el prototipo de llamada. Estarán en un miembro fuente independiente para que sea utilizado como /Copy tanto por el fuente del componente como los fuentes de los posibles programas que lo utilicen.


          ** Estrutura datos basicos de Clientes
    DDs_BasClie       DS                  QUALIFIED
    D IdCliente                     10  0
    D Nombre                        50
    D Apellidos                     50
    D Direccion                     50
    D IdPais                         3
    D DsPais                        50
    D IdTipCli                       1
    D DsTipCli                      50

    ** Estructura seleccionador de datos
    DDs_SelClie       DS                  QUALIFIED
    D K_IdCliente                   10  0
    D S_DsCliente                   50
    D S_IdPais                       3
    D S_IdTipCli                     1

    ** Prototipo de lista de clientes.
    DObt_LstClientes  PR
    D P_DatosClie                         Dim(99) LikeDs(Ds_BasClie)
    D P_NumReg                       2  0
    D P_TotReg                      10  0
     *Opcionales
    D P_Pag                          6  0 Const OPTIONS(*NOPASS)
    D P_RegCarPag                    3  0 Const OPTIONS(*NOPASS)
    D P_OrderBy                      2    Const OPTIONS(*NOPASS)
    D P_Sel                               LikeDs(Ds_SelClie) Const
    D                                     OPTIONS(*NOPASS)


    Está compuesto por:
    • (Ds_BasClie) Estructura de datos con los campos que se recuperarán de la instrucción SQL y que estarán en el array de datos que se devuelve.
    • (Ds_SelClie) Estructura de datos con los campos que se permite utilizar para seleccionar (se utilizarán en WHERE) para filtrar la sentencia SQL.
      • (K_) Seleccionador de clave primaria del fichero, en este ejemplo, será el código de cliente.
      • (S_) Otros posibles seleccionadores según la definición que se haga en el componente. 
    • (Obt_LstClientes) La definición del prototipo (interfaz) de llamada al componente. Más adelante explicaré los parámetros del mismo.

    Al principio del fuente del componente se utiliza el /COPY para “cargar” las estructuras de datos y los prototipos de los componentes. 

    /COPY *LIBL/QRPGLESRC,BAN01M1CP

    Fuente del componente. Obt_LstClientes en BAN01M1

    Parámetros

    El componente tendrá la siguiente definición de parámetros: