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.
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.
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.
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.
Fernando gracias por tan excelente blog, esperando lo completes con los ejemplos de binder y mas sobre programación avanzada con SQL Embebido.
ResponderEliminarSaludos.
Voy a ver si saco tiempo para volver a actualizar el blog añadiendo lo que me pides
ResponderEliminarHey Fernando, me uno a Javier con las felicitaciones y apoyo la noción que puedas agregas más ejemplos de Sql embebido... Saludos Compa.
ResponderEliminar