Serie ficheros virtuales

 

 

 

C Ficheros virtuales




C.2 Manuales de usuario. 

 

 

  C.2.1 Manual del usuario del programa de servicio SRRCW

   

    C.2.1.1 Lista de procedimientos por orden alfabético

    C.2.1.2 Lista de procedimientos por grupos funcionales

    C.2.1.3 Detalle de procedimientos

 

      C.2.1.3.1 Estructura de soporte  

      C.2.1.3.2 Un esquema resumen de uso típico

                -Definir las estructuras de soporte de los ficheros 

                -Crear los ficheros  

                -Establecer los bucles de proceso

                  Carga, lectura, actualización, salida, etc. 

                -Cerrar la aplicación 

  

      C.2.1.3.3 Funciones de gestión de objetos  

        C.2.1.3.3.1 Creación de ficheros. NEW, NOW y RESIZE

        C.2.1.3.3.2 CRTLF. Creación de lógicos (Vías de acceso suplementarias)  

        C.2.1.3.3.3 CLRF. Vaciado de datos  

        C.2.1.3.3.4 ERASE. Eliminación completa de un archivo o una base de datos

        C.2.1.3.3.5 CLOSE. Cierre de la aplicación  

 

      C.2.1.3.4 Funciones de caché básico. Núcleo del sistema  

         C.2.1.3.4.1 Grupo CHAIN (Recuperación de datos por clave)  

         C.2.1.3.4.2 Grupo WRITE (Grabación de datos)  

 

      C.2.1.3.5 Funciones derivadas directas  

        C.2.1.3.5.1 Grupo UPDATE. Actualización de ítem por clave  

        C.2.1.3.5.2 Grupo DELET. Eliminación de ítem por clave

 

      C.2.1.3.6 Funciones derivadas intrínsecamente del orden

        C.2.1.3.6.1 Grupo posicionamiento (SETLL...)  

        C.2.1.3.6.2 Grupo lectura (READ...)

 

      C.2.1.3.7 Extensiones de base de datos. CPY y DUP

      C.2.1.3.8 Persistencia de datos. RSTF y SAVF  

      C.2.1.3.9 Grupo informativo y de control. INF, NAME y NID

 

      C.2.1.3.10 Pilas y colas

        C.2.1.3.10.1 Grupo emulación pilas (LIFO)

        C.2.1.3.10.2 Grupo emulación colas (FIFO)  

 

 

                                                                                                      ________

 


 

C.2.1 Manual del usuario del programa de servicio SRRCW

 

 

Este documento tiene como propósito presentar un manual de uso de los servicios de SRRCW desde programas escritos en C. Se repasarán los distintos procedimientos y se ilustrarán con ejemplos tomados de los programas de muestra que se han utilizado en los interfaces de pantalla que se han ido presentando anteriormente.

 

Esta metodología se repetirá en distintas entregas posteriores dedicadas a otros lenguajes en su formato específico.

 

 

                                                                                                      ________

 

 

 

C.2.1.1 Lista de procedimientos por orden alfabético

 

 long SRRCW_CHAIN(const char *cFILE, const void *vClav, void *vDato,  long lLong);

 long SRRCW_CHAIN(const char *cFILE, const void *vClav, void *vDato);

 long SRRCW_CHAIN(const char *cFILE, void *vClav);

 

short int SRRCW_CLOSE(void);

 

 short int SRRCW_CLRF(const char *cFILE, long *lNBAJp);

 short int SRRCW_CLRF(const char *cFILE);

 

 long SRRCW_CPY(const char *cORG, const char *cDES, short int iREP);

 long SRRCW_CPY(const char *cORG, const char *cDES);

 

 long SRRCW_CRTLF(const char *cLF, const char *cPF, int iKPOS, int iKLEN);

 

 long SRRCW_DELETE(const char *cFILE, const void *vClav, long lLong);

 long SRRCW_DELETE(const char *cFILE, const void *vClav);

 

 long SRRCW_DUP(const char *cDES, const char *cORG);

 

 short int SRRCW_ERASE(const char *cFILE);

 

 long SRRCW_FIFO_NEW(const char *cFIFO, long lDimD, long lMaxNreg);

 long SRRCW_FIFO_NEW(const char *cFIFO, long lDimD);

 

 short int SRRCW_FIFO_READ(const char *cFIFO, void *vDato, char cOp);

 short int SRRCW_FIFO_READ(const char *cFIFO, void *vDato);

 

 long SRRCW_FIFO_WRIT(const char *cFIFO, const void *vDato);

 

 short int SRRCW_INF(const char *cFILE, int *iDimCp, long *lDimDp, long *lNÍTEMp, long *lBAJASp, long *lNIDDp);

 

 long SRRCW_LIFO_NEW(const char *cLIFO, long lDimD, long lMaxNreg);

 long SRRCW_LIFO_NEW(const char *cLIFO, long lDimD);

 

 short int SRRCW_LIFO_READ(const char *cLIFO, void *vDato, char cOp);

 short int SRRCW_LIFO_READ(const char *cLIFO, void *vDato);

 

 long SRRCW_LIFO_WRIT(const char *cLIFO, const void *vDato);

 

 char* SRRCW_NAME(const char *cFILE);

 

 long SRRCW_NEW(const char *cFILE, int iDimC, long lDimD, long lMaxNreg);

 long SRRCW_NEW(const char *cFILE, int iDimC, long lDimD);

 long SRRCW_NEW(const char *cFILE, int iDimC);

 

 long SRRCW_NID(const char *cFILE);

 

 long SRRCW_NOW(const char *cFILE, int iDimC, long lDimD, long lMaxNreg);

 long SRRCW_NOW(const char *cFILE, int iDimC, long lDimD);

 long SRRCW_NOW(const char *cFILE, int iDimC);

 

 short int SRRCW_READ(const char *cFILE, long lINDIp, void *vDato,  void *vClav);

 short int SRRCW_READ(const char *cFILE, long lINDIp, void *vDato);

 

 long SRRCW_READE(const char *cFILE, const void *vCLVp, long lLong, void *vDato, void *vClav);

 long SRRCW_READE(const char *cFILE, const void *vCLVp, long lLong,  void *vDato);

 

 long SRRCW_READPE(const char *cFILE, const void *vCLVp, long lLong,  void *vDato,   void *vClav);

 long SRRCW_READPE(const char *cFILE, const void *vCLVp, long lLong,  void *vDato);

 

 short int SRRCW_RESIZE(const char *cFILE, long lMaxNreg);

 

 long SRRCW_RSTF(const char *cFILE, short int iDES);

 long SRRCW_RSTF(const char *cFILE);

 

 long SRRCW_SAVF(const char *cFILE, short int iDES);

 long SRRCW_SAVF(const char *cFILE);

 

 long SRRCW_SETEQ(const char *cFILE, const void *vCLVp, long lLong);

 long SRRCW_SETEQ(const char *cFILE, const void *vCLVp);

 

 long SRRCW_SETGT(const char *cFILE, const void *vCLVp, long lLong);

 long SRRCW_SETGT(const char *cFILE, const void *vCLVp);

 

 long SRRCW_SETGTT(const char *cFILE, const void *vCLVp, long lLong);

 long SRRCW_SETGTT(const char *cFILE, const void *vCLVp);

 

 long SRRCW_SETLL(const char *cFILE, const void *vCLVp, long lLong);

 long SRRCW_SETLL(const char *cFILE, const void *vCLVp);

 

 long SRRCW_UPDATE(const char *cFILE, const void *vClav, const void *vDato,  long lLong);

 long SRRCW_UPDATE(const char *cFILE, const void *vClav, const void *vDato);

 long SRRCW_UPDATE(const char *cFILE, const void *vDato);

 

 long SRRCW_VER(const char *cFILE, const void *vClav);

 

 long SRRCW_WRITE(const char *cFILE, const void *vClav, const void *vDato);

 long SRRCW_WRITE(const char *cFILE, const void *vDato);

 


                                                                                                      ________



 

C.2.1.2 Lista de procedimientos por grupos funcionales

 

//------------------------------------------------------------------------------------------

// Funciones de gestión de objetos

//------------------------------------------------------------------------------------------

 

// Crear. Limpia datos previos si existieran

 

long SRRCW_NEW(const char *cFILE, int iDimC, long lDimD, long lMaxNreg);

long SRRCW_NEW(const char *cFILE, int iDimC, long lDimD);

long SRRCW_NEW(const char *cFILE, int iDimC);

 

 

// Crear. Sin limpiar datos previos

 

long SRRCW_NOW(const char *cFILE, int iDimC, long lDimD, long lMaxNreg);

long SRRCW_NOW(const char *cFILE, int iDimC, long lDimD);

long SRRCW_NOW(const char *cFILE, int iDimC);

 

 

// Cambio del nº máximo de registros

 

short int SRRCW_RESIZE(const char *cFILE, long lMaxNreg);

 

 

// Creación de vías de acceso suplementarias

 

long SRRCW_CRTLF(const char *cLF, const char *cPF, int iKPOS, int iKLEN);

 

 

// Vaciado de datos

 

short int SRRCW_CLRF(const char *cFILE, long *lNBAJp);

short int SRRCW_CLRF(const char *cFILE);

 

 

 

// Eliminación completa

 

short int SRRCW_ERASE(const char *cFILE);

 

 

 

// Cierre total

 

short int SRRCW_CLOSE(void);

 

 

 

//------------------------------------------------------------------------------------------

// Funciones de caché básico. Núcleo del sistema

//------------------------------------------------------------------------------------------

 

// Grupo CHAIN

 

long SRRCW_CHAIN(const char *cFILE, const void *vClav, void *vDato, long lLong);

long SRRCW_CHAIN(const char *cFILE, const void *vClav, void *vDato);

long SRRCW_CHAIN(const char *cFILE, void *vClav);

 

long SRRCW_VER(const char *cFILE, const void *vClav);

 

 

 

// WRITE

 

long SRRCW_WRITE(const char *cFILE, const void *vClav, const void *vDato);

long SRRCW_WRITE(const char *cFILE, const void *vDato);

 

 

 

// Funciones derivadas directas

 

 

// UPDATE

 

long SRRCW_UPDATE(const char *cFILE, const void *vClav, const void *vDato, long lLong);

long SRRCW_UPDATE(const char *cFILE, const void *vClav, const void *vDato);

long SRRCW_UPDATE(const char *cFILE, const void *vDato);

 

 

 

// Funciones derivadas intrínsicamente del orden

 

 

// DELETE

 

long SRRCW_DELETE(const char *cFILE, const void *vClav, long lLong);

long SRRCW_DELETE(const char *cFILE, const void *vClav);

 

short int SRRCW_REORGANIZE(const char *cFILE, long *lNBAJp);

short int SRRCW_REORGANIZE(const char *cFILE);

 

 

// Grupo Posicionamiento

 

 

long SRRCW_SETEQ(const char *cFILE, const void *vCLVp, long lLong);

long SRRCW_SETEQ(const char *cFILE, const void *vCLVp);

 

 

long SRRCW_SETGT(const char *cFILE, const void *vCLVp, long lLong);

long SRRCW_SETGT(const char *cFILE, const void *vCLVp);

 

 

long SRRCW_SETGTT(const char *cFILE, const void *vCLVp, long lLong);

long SRRCW_SETGTT(const char *cFILE, const void *vCLVp);

 

 

long SRRCW_SETLL(const char *cFILE, const void *vCLVp, long lLong);

long SRRCW_SETLL(const char *cFILE, const void *vCLVp);

 

 

 

// Grupo READ

 

short int SRRCW_READ(const char *cFILE, long lINDIp, void *vDato, void *vClav);

short int SRRCW_READ(const char *cFILE, long lINDIp, void *vDato);

 

 

long SRRCW_READE(const char *cFILE, const void *vCLVp, long lLong, void *vDato, void *vClav);

long SRRCW_READE(const char *cFILE, const void *vCLVp, long lLong, void *vDato);

 

 

long SRRCW_READPE(const char *cFILE, const void *vCLVp, long lLong, void *vDato, void *vClav);

long SRRCW_READPE(const char *cFILE, const void *vCLVp, long lLong, void *vDato);

 

 

 

//------------------------------------------------------------------------------------------

// Extensión de base de datos

//------------------------------------------------------------------------------------------

 

// Copia de datos

 

long SRRCW_CPY(const char *cORG, const char *cDES, short int iREP);

long SRRCW_CPY(const char *cORG, const char *cDES);

 

 

// Duplicacion de bases de datos virtuales

 

long SRRCW_DUP(const char *cDES, const char *cORG);

 

 

 

 

//------------------------------------------------------------------------------------------

// Persistencia de datos

//------------------------------------------------------------------------------------------

 

// Restauración desde fichero físico

 

long SRRCW_RSTF(const char *cFILE, short int iDES);

long SRRCW_RSTF(const char *cFILE);

 

 

// Salvado a fichero físico

 

long SRRCW_SAVF(const char *cFILE, short int iDES);

long SRRCW_SAVF(const char *cFILE);

 

 

 

//------------------------------------------------------------------------------------------

// Grupo informativo y de control

//------------------------------------------------------------------------------------------

 

short int SRRCW_INF(const char *cFILE, int *iDimCp, long *lDimDp, long *lNÍTEMp, long *lBAJASp, long *lNIDDp);

char* SRRCW_NAME(const char *cFILE);

 

long SRRCW_NID(const char *cFILE);

 

 

 

//------------------------------------------------------------------------------------------

// Grupos de emulación de pilas y colas

//------------------------------------------------------------------------------------------

 

// Grupo emulación pilas

 

long SRRCW_LIFO_NEW(const char *cLIFO, long lDimD, long lMaxNreg);

long SRRCW_LIFO_NEW(const char *cLIFO, long lDimD);

 

short int SRRCW_LIFO_READ(const char *cLIFO, void *vDato, char cOp);

short int SRRCW_LIFO_READ(const char *cLIFO, void *vDato);

 

long SRRCW_LIFO_WRIT(const char *cLIFO, const void *vDato);

 

 

 

// Grupo emulación colas

 

long SRRCW_FIFO_NEW(const char *cFIFO, long lDimD, long lMaxNreg);

long SRRCW_FIFO_NEW(const char *cFIFO, long lDimD);

 

short int SRRCW_FIFO_READ(const char *cFIFO, void *vDato, char cOp);

short int SRRCW_FIFO_READ(const char *cFIFO, void *vDato);

 

long SRRCW_FIFO_WRIT(const char *cFIFO, const void *vDato);

 

                                                                                                      ________

 

C.2.1.3 Detalle de procedimientos

 

 

C.2.1.3.1 Estructura de soporte

 

A lo largo de este manual dedicado a los servicios de SRRCW, se irán ilustrando los procedimientos utilizando la estructura de datos sDsF, que se compone de una subestructura de clave principal, una subestructura de clave alternativa y una subestructura de datos, que se detallan a continuación:

 

 

 

// Definición de la estructura del fichero virtual de pruebas sDsF

 

static struct sDsKD

{

 struct sDsK sDk;     // Clave principal. [i,j]

 struct sDsK01 sDk01; // Clave alternativa. [j,i]. Soporte del fichero lógico de

                      // lectura inversa

 struct sDsD sDd;     // Datos asociados

} sDsF;

 

 

 

 

// Definición de la subestructura de clave principal, para acceso a nodos i,j

 

struct sDsK

{

 long li; // Índice i del nodo

 long lj; // Índice j del nodo

};

 

 

 

// Ds de claves del fichero virtual "lógico" de pruebas, para lectura inversa

 

struct sDsK01

{

 long lji; // Índice inverso ji = N - ij del nodo

 char EOR; // Marca de fin de estructura

};

 

 

 

// Ds datos del fichero virtual de pruebas

 

struct sDsD // Estructura de datos de pruebas

{

 long lij;   // Índice ij del nodo [Contador absoluto: for(i(forj(++ij))]

 double dij; // ij en formato double

};

 

 

 

Las instrucciones que se presentan se incluyen en el programa de muestra PruebasW, interfaz de demostración de las funciones de SRRCW, que da soporte a las presentaciones del manual y a los ejemplos de desarrollo de la primera parte del libro.

 

 

Debe tenerse en cuenta que PruebasW es un laboratorio formal de pruebas de SRRCW, más pensado como soporte del manual que como colección de ejemplos de aplicación práctica, para los que se encuentran capítulos específicamente dedicados en otras zonas del libro.

 

Las instrucciones se mostrarán en formato completo y reducido, aunque recordando que éste último se emplea por comodidad, ya que no es válido en ANSI C puro donde no se soporta la sobrecarga multifunción.

 

Por la misma razón, en iSeries se utiliza un interfaz auxiliar en ILE-RPG, SRAGM, para poder invocar las funciones en formato ampliado y reducido.

 

Posteriormente se presenta la versión del manual para la clase wFile con más ejemplos y elaboración de presentaciones gráficas que pueden extrapolarse perfectamente aquí.

 

 

Las instrucciones se presentarán por grupos funcionales, acompañadas de extractos de PruebasW, programa del que a continuación se muestra una imagen:

 

 

 

 

Durante la ejecución de PruebasW se va actualizando periódicamente un registro de estado que permite una monitorización en paralelo al ejecutar el botón “Monitor”, arrancándose entonces el proceso “MonitorW”, como sigue:

 

void CPruebasWDlg::OnBUTTONMonitor()

{

 int iResul = 0; // Control de invocaciones

 

 

 // Invoca a la pantalla de monitorización utilizando una invocación de aplicación windows

 

 iResul = WinExec("MonitorW", SW_SHOWNORMAL);

 

 return;

}

 

 

Veamos una imagen del monitor de control asociado que se arranca:

 

 

 

                                                                                                      ________

 

 

Recíprocamente, en el programa MonitorW se lee y presenta el estado de las pruebas así como se graba la parada y reanudación de pruebas, como sigue:

 

void CMonitorWDlg::OnButtonver()

{

 char cN[33]; // Aux.paso de nombre de rutina en proceso de prueba

 

 

 // Lee estado actual de pruebas

 

 if (pMonitorW_dat = fopen("MonitorW.dat", "rb"))

 {

 

  fread (&MonitorW_reg, sizeof(MonitorW_reg), 1, pMonitorW_dat);

  if (!feof(pMonitorW_dat))

  {

   memcpy(cN, MonitorW_reg.cN, 33);

   m_cN = cN;

   m_li = MonitorW_reg.li;

   m_lj = MonitorW_reg.lj;

  }

 

 

  // Cierra archivo de solicitud de parada leído

 

  fclose(pMonitorW_dat);

 }

 

 

 // Presenta los valores actuales

 

 UpdateData(false);

}

                                                                                                      ________

 

void CMonitorWDlg::OnBUTTONStop()

{

 // Graba valor de parada

 

 MonitorWstop_reg.is = 1;

 

 

 if (pMonitorWstop_dat = fopen("MonitorWstop.dat", "wb"))

 {

   // Salva datos actuales

 

   fwrite (&MonitorWstop_reg, sizeof(MonitorWstop_reg), 1, pMonitorWstop_dat);

 

 

   // Cierra archivo grabado

 

   fclose(pMonitorWstop_dat);

  }

 

 }

 

 

 La rutina de activación es idéntica, pero cambiando la instrucción inicial a

 

 // Graba valor de reanudación

 

 MonitorWstop_reg.is = 1;

                                                                                                      ________


 

Tras presentar esta codificación común a las pruebas, presentemos ahora un esquema resumen del uso típico de los bucles de proceso y a continuación entraremos en la exposición del manual propiamente dicho

 

                                                                                                      ________

 

 

C.2.1.3.2 Un esquema resumen de uso típico

 

 

Un uso típico de la aplicación se puede esquematizar como

 

 

- Definir las estructuras de soporte de los ficheros, tipo

 

struct sKD

{

 struct sK DK;     // Clave principal

 struct sK01 DK01; // Clave alternativa

 struct sD DD;     // Datos

} DSKD;

 

 

 

- Crear los ficheros de soporte con SRRCW_NEW, como en

 

 

    // Físico base

 

    lNID = SRRCW_NEW("FILE", sizeof(DSKD.DK), sizeof(DSKD));

 

 

    // Lógico acceso alternativo

 

    lNID01 = SRRCW_CRTLF("FILE01", "FILE", sizeof(DSKD.DK) + 1, sizeof(DSKD.DK01));

 

 

 

- Establecer los bucles de proceso.

 

 

Tanto de carga, como en

 

 

    [Normalmente habrá una inicialización previa utilizando SRRCW_CLRF("FILE");]

 

    for(i=1;i<=n;++i)

    {

     . . .

     SRRCW_WRITE("FILE", &DSKD);            [ También puede utilizarse SRRCW_VER("FILE", &DSK); ]

    }

 

 

 

Como de lectura, actualización, salida de resultados, etc, similar a

 

 

[Opcionalmente habrá un posicionamiento con SRRCW_SETLL("FILE", &DSKD);]

 

for(i=1;i<=n;++i)

{

    SRRCW_READ("FILE", i, &DSKD); [SRRCW_READE/UPDATE/CHAIN("FILE", &DSKD); ...]

    ...

   }

 

 

- Por último se cerraría la aplicación

 

   SRRCW_CLOSE();



 

     (Esto último no es preciso en iSeries, al finalizar el grupo de activación se depura toda la memoria dinámica automáticamente)

 

                                                                                                      ________ 

 

 

C.2.1.3.3 Funciones de gestión de objetos (NEW, NOW, RESIZE, CRTLF, CLRF, ERASE y CLOSE)

 

 

Se presentan a continuación las funciones

 

     SRRCW_NEW, SRRCW_NOW, SRRCW_RESIZE, SRRCW_CRTLF, SRRCW_CLRF, SRRCW_ERASE y SRRCW_CLOSE

 

                                                                                                      ________

 

 

C.2.1.3.3.1 Creación de ficheros. NEW, NOW y RESIZE

 

 

// Crear. Limpia datos previos si existieran

 

//-----------------------------------------------------------------

// FUNCION....: SRRCW_NEW

//

// DESCRIPCION: Genera un identificador interno para el nombre de

// fichero solicitado. Si existe previamente lo limpia

//

//

// PARAMETROS.: Formato completo

//

// (entrada) iDimC: Dimensión claves del nuevo grupo de Ítems

//           lDimD: Dimension datos del nuevo grupo de Ítems

//        lMaxNreg: Máximo número de ítems a generar

//

//

// PARAMETROS.: Formato compacto

//

// (entrada) iDimC: Dimensión claves del nuevo grupo de Ítems

//           lDimD: Dimension datos del nuevo grupo de Ítems

//

//

// PARAMETROS.: Formato compacto reducido

//

// (entrada) iDimC: Dimensión claves y datos del nuevo fichero

//

//

// RETORNO....:

//               0: Error de Proceso (Memoria agotada, ...)

//              >0: Nuevo Identificador (NID)

//

//-----------------------------------------------------------------

long SRRCW_NEW(const char *cFILE, int iDimC, long lDimD, long lMaxNreg);

long SRRCW_NEW(const char *cFILE, int iDimC, long lDimD); [2500000L]

long SRRCW_NEW(const char *cFILE, int iDimC); [iDimC]

 

 

 

// Crear. Sin limpiar datos previos

 

//-----------------------------------------------------------------

// FUNCION....: SRRCW_NOW

//

// DESCRIPCION: Genera un identificador interno para el nombre de

// fichero solicitado, si no existe previamente.

//

//

// PARAMETROS.: Formato completo

//

// (entrada) iDimC: Dimensión claves del nuevo grupo de Ítems

//           lDimD: Dimension datos del nuevo grupo de Ítems

//        lMaxNreg: Máximo número de ítems a generar

//

//

// PARAMETROS.: Formato compacto

//

// (entrada) iDimC: Dimensión claves del nuevo grupo de Ítems

//           lDimD: Dimension datos del nuevo grupo de Ítems

//

//

// PARAMETROS.: Formato compacto reducido

//

// (entrada) iDimC: Dimensión claves y datos del nuevo fichero

//

//

// RETORNO....:

//               0: Error de Proceso (Memoria agotada, ...)

//              >0: Nuevo Identificador (NID)

//

//-----------------------------------------------------------------

long SRRCW_NOW(const char *cFILE, int iDimC, long lDimD, long lMaxNreg);

long SRRCW_NOW(const char *cFILE, int iDimC, long lDimD); [2500000L]

long SRRCW_NOW(const char *cFILE, int iDimC); [iDimC]

 

 

 

//-------------------------------------------------------------------

// FUNCION....: SRRCM_RESIZE

//

// DESCRIPCION: Cambia el nº máximo de registros de un fichero virtual

//

// PARAMETROS.:

// (entrada) lNIDp: Identificador del fichero virtual

//        lMaxNreg: Nuevo nº máximo número de ítems a generar

// RETORNO....:

//               0: Cambio realizado satisfactoriamente

//               1: Error de Proceso

//

//-------------------------------------------------------------------

short int SRRCW_RESIZE(const char *cFILE, long lMaxNreg);

 

La rutina permite cambiar el número máximo de registros que admitirá el fichero de forma dinámica. Obviamente, si se trata de cambiar a un número inferior al actualmente utilizado, la petición se rechazará y retornará valor nulo.

 

 

Ejemplos:

 

 ...

 

 short int er = 0; // Control de invocaciones erróneas

 long lNID = 0;    // Nid asignado al fichero virtual "físico" de pruebas

 

 lNID = SRRCW_NEW("PRUEBASW", sizeof(sDsK), sizeof(sDsKD), 50000);

 if (!lNID) return;

 

 ...

 

 

Con ésta instrucción se crea un fichero virtual de longitud de clave la de la subestructura sDsK presentada antes y de tamaño global el de la estructura completa sDsKD.

 

También se indica en la instrucción que el nºmáximo de registros del fichero sería 50000. En caso de no indicarse el máximo se toma el definido en la constante lMAXNREG [2500000]

 

 

Precisamente se han incluido dos constantes de límite en el programa para prevenir un colapso de la máquina en caso de invocación enbuclada.

 

El primero es la constante citada lMAXNREG que contempla el máximo número de registros en un fichero y que se inicializa con el generoso límite de 2500000. En cualquier caso este límite no es absoluto, siempre puede cambiarse invocando a SRRCW_RESIZE.

 

El segundo límite es el del número máximo de ficheros virtuales lMAXF que esta fijado en 1000000. Este límite es absoluto, para cambiarlo habría que recompilar el programa núcleo(SRRCM).

 

 

El ejemplo podría continuar entonces como sigue

 

...

 

er = SRRCW_RESIZE("PRUEBASW", 100000);

 

...

 

En donde el límite se amplia a 100000.

 

                                                                                                      ________

 

 

C.2.1.3.3.2 CRTLF. Creación de lógicos (Vías de acceso suplementarias)

 

//--------------------------------------------------------------------------------------

//

// Función SRRCW_CRTLF

//

// Descripción Crea un lógico en base a un fichero físico previo

//

// Importante La clave del físico debe ocupar las 1ras.posiciones del registro

//

// Parámetros

// (entrada) cLF Nombre del fichero lógico a crear

//           cPF Nombre del fichero físico base

//         iKPOS Posición de comienzo de clave del LF en los datos del registro

//              (Formato 1..N RPG)

//         iKLEN Longitud de la clave del LF que se está creando

//

// Retorno

//         0 Error de proceso

//         >0 NID del fichero en memoria

//

//--------------------------------------------------------------------------------------

long SRRCW_CRTLF(const char *cLF, const char *cPF, int iKPOS, int iKLEN);

 

 

Ejemplo:

 

 ...

 

 lNID01 = SRRCW_CRTLF("PRUEBASW01", "PRUEBASW", sizeof(sDsK) + 1, sizeof(sDsK01));

 if (!lNID01) return;

 

 ...

 

Esta instrucción amplia la base de datos basada en el fichero base PRUEBASW con una vía lógica de nombre PRUEBASW01, cuya clave comienza en la posición siguiente a la de la vía principal, esto es, en sDsK01.

 

Normalmente agrupo las sentencias de creación de bases de datos, primero los físicos y luego los lógicos, pero no hay restricciones al respecto, se puede estar trabajando normalmente con un fichero, tener la necesidad puntual de un acceso alternativo, generarlo en el momento, usarlo y luego eliminarlo. Obviamente, lo que si que debe estar en línea desde el comienzo es la propia definición de las estructuras de soporte de la base de datos completa, tanto de la vía principal como de las secundarias.

 

Al crear lógicos bajo MsC++ hay que tener en cuenta las notas relativas al tamaño de las estructuras que se consideraron precisamente en el capítulo de estructuras de la primera parte del libro.

 

Tal como se explicaba allí, si procede, deben añadirse campos de relleno sin uso (filler) al final de cada subestructura para garantizar que el tamaño aparente y el real coincidan.

 

En la plataforma iSeries no se precisa tener en cuenta estas consideraciones.

 

                                                                                                      ________

 

C.2.1.3.3.3 CLRF. Vaciado de datos

 

//-------------------------------------------------------------------------------------

// Función SRRCW_CLRF

//

// DESCRIPCION: CLRPFM de un fichero

//

//

// PARAMETROS.: Formato completo

//

// (entrada) cFILE: Nombre del fichero solicitado

// (salida) lNBAJp: Nºbajas procesadas

//

//

// PARAMETROS.: Formato compacto

//

// (entrada) cFILE: Nombre del fichero solicitado

//

//

// RETORNO....:

// 0: O.K.

// >0: Error de proceso

//

//-------------------------------------------------------------------------------------

short int SRRCW_CLRF(const char *cFILE, long *lNBAJp);

short int SRRCW_CLRF(const char *cFILE);

 

 

Al aplicarse sobre cualquiera de los ficheros de una base de datos, sea en el fichero físico o en cualquiera de sus lógicos, se eliminan todos los registros de la misma, tanto del fichero solicitado como de los relacionados con él.

 

Dicho de otra manera, si se limpia uno cualquiera de los ficheros de una base de datos, se limpian todos.

 

 

En su versión completa, proporciona el dato informativo del número neto de registros suprimidos, esto es

 

lNBAJp = lNÍTEM - lBAJAS; donde lNÍTEM es el nº de registros direccionado y lBAJAS aquellos que ya estaban suprimidos

 

 

Tras su ejecución, la base de datos queda con lNÍTEM = lBAJAS = 0.

 

 

Ejemplo:

 

 ...

 er = SRRCW_CLRF("PRUEBASW");

 ...

 

 

Vacia de registros a PRUEBASW y a su lógico PRUEBASW01

 

                                                                                                      ________

 

 

C.2.1.3.3.4 ERASE. Eliminación completa de un archivo o de una base de datos

 

//-------------------------------------------------------------------------------------

// Función SRRCW_ERASE

//

// DESCRIPCION: Borra un fichero ("DLTF")

//

//

// PARAMETROS.:

//

// (entrada) cFILE: Nombre del fichero solicitado

//

//

// RETORNO....:

//               0: O.K.

//               >0: Error de proceso

//

//-------------------------------------------------------------------------------------

short int SRRCW_ERASE(const char *cFILE);

 

 

Tal como se ha implementado, ERASE elimina bases de datos si se ejecuta sobre los ficheros base, y sólo la vía de acceso solicitada si se aplica sobre lógicos.

 

 

Ejemplo:

 

 ...

 er = SRRCW_ERASE("PRUEBASWDUP");

 ...

 

 

Al ejecutarse, se elimina la base de datos virtual compuesta por el fichero PRUEBASWDUP y su lógico dependiente PRUEBASWDUP01.

 

 

Si por el contrario se hubiese ejecutado

 

 ...

 er = SRRCW_ERASE("PRUEBASWDUP01");

 ...

 

sólo se habría eliminado la vía de acceso PRUEBASWDUP01 pero no el fichero base PRUEBASWDUP.

 

Para volver a utilizar PRUEBASWDUP01 tendría que volver a ser generado con SRRCW_CTRLF.

 

                                                                                                      ________ 

 

C.2.1.3.3.5 CLOSE. Cierre de la aplicación

 

//--------------------------------------------------------------------------------------

//

// Función: SRRCW_CLOSE

//

// Descripción: Cierre. Depuración de variables globales dinámicas

//

// Parámetros: Ninguno

//

// Retorno:

//               0: OK

//              >0: Error de proceso

//

//--------------------------------------------------------------------------------------

short int SRRCW_CLOSE(void);

 

 

Cierra el aplicativo eliminando todas las bases de datos generadas tanto las internas que utiliza SRRCW para mantener las interrelaciones de base de datos, como las creadas por el usuario y libera la memoria de todas las variables de trabajo que hayan utilizado asignación dinámica.

 

Su utilización se reserva a botones OnCancel de salida final, donde se especificaría

 

 ...

 er = SRRCW_CLOSE();

 ...

 

 

En teoría no es estrictamente necesario, el sistema debería hacer lo mismo automáticamente, pero se observa en la práctica que si se deja la tarea al sistema se ejecuta en segundo plano y que puede llevar su tiempo.

 

Mientras, la memoria no está disponible y si se arrancan otras aplicaciones el sistema puede colapsar.

 

 

Por el contrario la respuesta de SRRCW_CLOSE es inmediata evitando esos problemas.

 

 

En iSeries la liberación automática al terminar un grupo de activación es una realidad inherente al sistema y la función no se precisa.

 

                                                                                                      ________

 

 

C.2.1.3.4 Funciones de caché básico. Núcleo del sistema

 

 

C.2.1.3.4.1 Grupo CHAIN (Recuperación de datos por clave)

 

//-------------------------------------------------------------------------------------

// Función SRRCW_CHAIN

//

// DESCRIPCION: Recupera un Ítem de Memoria por Clave

//

//

// PARAMETROS.: Formato extendido

//

// (entrada) cFILE: Nombre del fichero asociado

// (entrada) vClav: Clave del Ítem

// (salida ) vDato: Datos del Ítem

// (entrada) lLong: Longitud para acceso por clave parcial igual

//

//

// PARAMETROS.: Formato completo

//

// (entrada) cFILE: Nombre del fichero asociado

//           vClav: Clave del Ítem

// (salida ) vDato: Datos del Ítem

//

//

// PARAMETROS.: Formato compacto

//

// (entrada) cFILE: Nombre del fichero asociado

//   (I/O)   vClav: Clave + datos del Ítem

//

//

// RETORNO....:

//               0: Error de Proceso (No encontrado, ...)

//               >0: Índice en memoria-claves del Ítem encontrado

//                     (formato 1..N)

//

//-------------------------------------------------------------------------------------

long SRRCW_CHAIN(const char *cFILE, const void *vClav, void *vDato, long lLong);

long SRRCW_CHAIN(const char *cFILE, const void *vClav, void *vDato);

long SRRCW_CHAIN(const char *cFILE, void *vClav);

 

 

Ejemplo:

 

 ...

 

 sDsF.sDk.li = li;
 SRRCAL_lLexi(&sDsF.sDk.li); // Ajuste de compatibilidad con memcmp en MsC++. No preciso en iSeries.

 

 sDsF.sDk.lj = lj;

 SRRCAL_lLexi(&sDsF.sDk.lj);

 lResul = SRRCW_CHAIN("PRUEBASW", &sDsF);

 

 ...

 

 

Se recupera un registro de PRRUEBASW según el diseño sDsF, de clave sDsF.sDk

 

 

 

Estas instrucciones son un extracto de la codificación de la rutina asociada al botón “CHAIN” del programa PruebasW, que mostramos ahora al completo para verlas enmarcadas dentro de un contexto de programa:

 

//----------------------------------------------------------------------------------

// Función: PrPruebasC

//

// Descripción: Pruebas de SRRCW. Lectura por demanda CHAIN

//

// Parámetros:

// (entrada) li : Nº de filas solicitado

//           lj : Nº de columnas solicitado

//

// Precondición: Debe haberse ejecutado PrPruebasW previamente
//

// Retorno: >0: Nº de ítems generados

//         <=0: Errores

//----------------------------------------------------------------------------------

long PrPruebasC(long p_li, long p_lj)

{

 short int er = 0; // Control de invocaciones erróneas

 long lResul = 0;  // Control de resultados

 long lINDI = 0;   // Índice de posicionamiento

 long li = 0;      // Variable de for índice i

 long lj = 0;      // Variable de for índice j

 long lij = 0;     // Variable de for índice ij

 long p_lij = 0;   // Variable de retorno

 

 long lN = p_li * p_lj; // Nºtotal teórico i,j

 

 div_t div_result;      // Soporte de división con resto y cociente para la monitorización periódica

 

 

 // Inicio de proceso

 

 er = PrMonitorW("SRRCW_CHAIN", 1, 1); // Graba registro de monitorización CHAIN 1 1

 if (er) return -1; // Control de parada externa desde MonitorW

 

 

 // Bucle de proceso

 

 lij = 0;

 

 for (li = 1; li <= p_li; ++li)

 for (lj = 1; lj <= p_lj; ++lj)

 {

  ++lij;

 

  div_result = div(lij, 551); // Monitorización cada medio millar de pasos aprox.

  if (!div_result.rem)

  {

   er = PrMonitorW("SRRCW_CHAIN", li, lj); // Graba registro monitorización i j

   if (er) return -lij; // Control de parada externa

  }

 

 

 // Núcleo de la prueba

 

 sDsF.sDk.li = li;

 SRRCAL_lLexi(&sDsF.sDk.li); // Ajuste de compatibilidad con memcmp en MsC++

 

 sDsF.sDk.lj = lj;

 SRRCAL_lLexi(&sDsF.sDk.lj);

 

 

 lResul = SRRCW_CHAIN("PRUEBASW", &sDsF);

 

 

 // Control de resultado erróneo (memoria agotada)

 

 if (!lResul)

 {

  return -(330000000 + li * 1000000 + lj);

 }

 

 // Verificación de contenido recuperado concordante con PrPruebasW

 

 SRRCAL_lLexi(&sDsF.sDk.li);

 SRRCAL_lLexi(&sDsF.sDk.lj);

 

 if (lij != sDsF.sDd.lij)

 {

  return -(440000000 + li * 1000000 + lj);

 }

}

 

 

 // Fin de proceso

 

 er = PrMonitorW("SRRCW_CHAIN", p_li, p_lj); // Graba monitorización final

 if (er) return -lij; // Control de parada externa

 

 

 return lij;

}

 

 

                                                                                                      ________

 

 

C.2.1.3.4.2 Grupo WRITE (Grabación de datos)

 

//-----------------------------------------------------------------------------------

// FUNCION....: SRRCW_WRITE

//

// DESCRIPCION: Salva un Ítem a memoria

//

//

// PARAMETROS Formato completo

//

// (entrada) cFILE: Fichero solicitado

//           vClav: Clave del Ítem

//           vDato: Datos del Ítem

//

//

// PARAMETROS Formato compacto

//

// (entrada) lNIDp: Identificador del Conjunto de Ítems asociado

//           vDato: Clave + datos del ítem

//

//

// RETORNO....:

//                0: Error de Proceso (Memoria out, ya existe...)

//               >0: Índice de Ítem-Clave Guardado Satisfactoriamente

//                     (Formato 1..N)

//-----------------------------------------------------------------------------------

long SRRCW_WRITE(const char *cFILE, const void *vClav, const void *vDato);

long SRRCW_WRITE(const char *cFILE, const void *vDato);

 

 

El formato extendido sólo se precisa si la clave y los datos no son contiguos, como por ejemplo en la grabación de registros en ficheros lógicos.

 

El formato reducido asume que clave y datos son contiguos, como es habitual en los ficheros físicos base.

 

 

Ejemplo:

 

 

Se graba un registro en PRPRUEBASW según el diseño sDsF definido previamente

 

 ...

 

 // Paso de claves

 

 sDsF.sDk.li = li;

 SRRCAL_lLexi(&sDsF.sDk.li); // Ajuste de compatibilidad con memcmp en MsC++. No preciso en iSeries.

 

 sDsF.sDk.lj = lj;

 SRRCAL_lLexi(&sDsF.sDk.lj);

 

 sDsF.sDk01.lji = lji;

 sDsF.sDk01.EOR = '*';

 SRRCAL_lLexi(&sDsF.sDk01.lji);

 

 

 // Paso de datos

 

 sDsF.sDd.lij = lij;

 sDsF.sDd.dij = (double) lij;

 

 

 p_lij = SRRCW_WRITE("PRUEBASW", &sDsF);

 

 ...

 

 

Estas instrucciones son un extracto de la codificación de la rutina asociada al botón “WRITE” del programa PruebasW, que mostramos ahora al completo para verlas enmarcadas dentro de un contexto de programa:

 

//-----------------------------------------------------------------------------------

// Función: PrPruebasW

//

// Descripción: Pruebas de SRRCW. Escritura

//

// Parámetros:

// (entrada) li : Nº de filas solicitado

//           lj : Nº de columnas solicitado

//

// Retorno: >0: Nº de ítems generados

//         <=0: Errores

//----------------------------------------------------------------------------------

long PrPruebasW(long p_li, long p_lj)

{

 short int er = 0; // Control de invocaciones erróneas

 long lINDI = 0;   // Índice de posicionamiento

 long li = 0;      // Variable de for índice i

 long lj = 0;      // Variable de for índice j

 long lij = 0;     // Variable de for índice ij

 long lji = 0;     // Variable de for índice ji

 long p_lij = 0;   // Variable de retorno

 

 long lN = p_li * p_lj; // Nºtotal teórico i,j

 

 div_t div_result;      // Soporte de división con resto y cociente para la monitorización periódica

 

 

 // Inicio de proceso

 

 er = PrMonitorW("SRRCW_WRITE", 1, 1); // Graba registro de monitorización WRITE 1 1

 if (er) return -1; // Control de parada externa desde MonitorW

 

 

 // Limpia la base de datos utilizada

 

 er = SRRCW_CLRF("PRUEBASW");

 

 

 // Bucle de proceso

 

 p_lij = 0;

 

 lji = lN + 1;

 

 for (li = 1; li <= p_li; ++li)

 for (lj = 1; lj <= p_lj; ++lj)

 {

  ++lij;

  --lji;

 

  div_result = div(lij, 551); // Monitorización cada medio millar de pasos aprox.

  if (!div_result.rem)

  {

   er = PrMonitorW("SRRCW_WRITE", li, lj); // Graba registro monitorización i j

   if (er) return -lij; // Control de parada externa

  }

 

 

  // Núcleo de la prueba

 

  sDsF.sDk.li = li;

  SRRCAL_lLexi(&sDsF.sDk.li); // Ajuste de compatibilidad con memcmp en MsC++

 

  sDsF.sDk.lj = lj;

  SRRCAL_lLexi(&sDsF.sDk.lj);

 

 

  sDsF.sDk01.lji = lji;

  sDsF.sDk01.EOR = '*';

  SRRCAL_lLexi(&sDsF.sDk01.lji);

 

 

  sDsF.sDd.lij = lij;

  sDsF.sDd.dij = (double) lij;

 

  p_lij = SRRCW_WRITE("PRUEBASW", &sDsF);

  if (!p_lij)

  {

   return - (1000000000 + li * 1000000 + lj);

  }

 }

 

 

 // Fin de proceso

 

 er = PrMonitorW("SRRCW_WRITE", p_li, p_lj); // Graba monitorización final

 if (er) return -lij; // Control de parada externa

 

 return lij;

}

                                                                                                      ________

 

 

En ocasiones sólo se precisa saber si se ha tratado un ítem previamente en el trabajo en curso, sin necesidad de recuperar los datos.

 

Para ello se dispone en este grupo de la función SRRCW_VER.

 

//-------------------------------------------------------------------------------------

// Función SRRCW_VER

//

// Descripción: Determina la existencia de un ítem en memoria

// Función resumen simple de CHAIN + WRITE (Ítem)

//

// Parámetros

// (entrada) cFILE: Fichero virtual de soporte de la verificación

//           vClav: Clave del ítem a verificar

//

// Retorno

//           0: Error de proceso (No encontrado...)

//         >0: Índice en memoria-clave encontrado, formato 1..N

//-------------------------------------------------------------------------------------

long SRRCW_VER(const char *cFILE, const void *vClav);

 

 

Ejemplo:

 

 ...

 

 sDsF.sDk.li = li;

 SRRCAL_lLexi(&sDsF.sDk.li); // Ajuste de compatibilidad con memcmp en MsC++. No se precisa en iSeries.

 

 sDsF.sDk.lj = lj;

 SRRCAL_lLexi(&sDsF.sDk.lj);

 lResul = SRRCW_VER("PRUEBASW", &sDsF);

 

 if (lResul) continue;

 

 ...

 

En el ejemplo, en el que se supone que se está ejecutando un bucle de proceso, al detectar con SRRCW_VER que un determinado ítem ya se ha procesado anteriormente, lo elude, continuando el proceso sólo con los ítems que no se han tratado antes y que al utilizar SRRCW_VER ya quedan marcados a su vez como tratados para posteriores consultas.

 

Es particularmente eficaz para enbuclamientos que leen ítems en un orden dado pero que a su vez deben procesar sin repeticiones sublistas de ítems que no siguen el orden primario.

 

                                                                                                      ________

 

C.2.1.3.5 Funciones derivadas directas

 

 

C.2.1.3.5.1 Grupo UPDATE. Actualización de ítem por clave

 

//------------------------------------------------------------------------------

// FUNCION....: SRRCW_UPDATE

//

// DESCRIPCION: Actualiza un Ítem en memoria

//

//

// PARAMETROS Formato extendido

//

// (entrada) cFILE: Fichero solicitado

// (entrada) vClav: Clave del Ítem

// (salida)  vDato: Datos del Ítem

// (entrada) lLong: Longitud para acceso por clave parcial igual

//

//

// PARAMETROS Formato completo

//

// (entrada) cFILE: Fichero solicitado

// (entrada) vClav: Clave del Ítem

// (salida)  vDato: Datos del Ítem

//

//

// PARAMETROS Formato compacto

//

// (entrada) cFILE: Fichero solicitado

// (I/O)     vDato: clave + datos del ítem

//

// RETORNO....:

//                 0: Error de Proceso (Memoria out, ya existe...)

//               >0: Índice en memoria de la clave del ítem asociado

//

//------------------------------------------------------------------------------

long SRRCW_UPDATE(const char *cFILE, const void *vClav, const void *vDato, long lLong);

long SRRCW_UPDATE(const char *cFILE, const void *vClav, const void *vDato);

long SRRCW_UPDATE(const char *cFILE, const void *vDato);

 

 

El formato extendido permite actualizar accediendo por una longitud de clave parcial.

 

El formato completo se precisa si la clave y los datos no son contiguos, como por ejemplo en la actualización de ficheros lógicos.

El formato reducido asume que clave y datos son contiguos, como es habitual en los ficheros físicos base.

 

SRRCW_UPDATE puede actualizar datos directamente sin necesidad de acceso previo con chain o read, aunque esto puede ser necesario si se precisa actualizar los datos mediante una manipulación dependiente de su valor previo.

 

Por otro lado se debe tener presente que SRRCW_UPDATE no puede actualizar directamente la parte de clave porque es la propia clave la que permite acceder al registro; si se precisa, debe emitirse un juego de SRRCW_DELETE + SRRCW_WRITE.

 

 

 

Ejemplo:

 

 ...

 

 // Pasamos el valor de clave para acceso por el lógico “PRUEBASW01” (También se actualizará el físico asociado de forma automática)

 

 sDsF.sDk01.lji = lji;

 SRRCAL_lLexi(&sDsF.sDk01.lji); // Ajuste de compatibilidad con memcmp en MsC++. No preciso en iSeries.

 

 

 

 // Accedemos a los datos ...

 

 lResul = SRRCW_CHAIN("PRUEBASW01", &sDsF.sDk01, &sDsF);

 

 if (!lResul) return;

 

 

 // ... los cambiamos parcialmente ...

 

 sDsF.sDd.lij++;

 

 

 // ... y los actualizamos

 

 lResul = SRRCW_UPDATE("PRUEBASW01", &sDsF.sDk01, &sDsF);

 

 if (!lResul) return;

 

 ...

 

 

Como se indica más arriba, podría haberse utilizado UPDATE sin necesidad de asociarlo a un chain anterior, si la modificación a efectuar no hubiese dependido de los datos previos.

 

 

Estas instrucciones son un extracto de la codificación de la rutina asociada al botón “UPDATE” del programa PruebasW.

 

                                                                                                    ________

 

 

C.2.1.3.5.2 Grupo DELETE. Eliminación de ítem por clave

 

//-------------------------------------------------------------------------------------

// Función SRRCW_DELETE

//

// Descripción Elimina un ítem de memoria

//

// Parámetros

// (entrada) cFILE Nombre del fichero asociado

//           vClav Clave del ítem

// lLong Longitud de acceso parcial, para borrado por clave parcial igual. Este parámetro es opcional.

// Es muy útil en bucles de purga de datos.

//

// Retorno

//  0 Error de proceso

// >0 Posición en memoria del ítem suprimido

//

//-------------------------------------------------------------------------------------

long SRRCW_DELETE(const char *cFILE, const void *vClav, long lLong);

long SRRCW_DELETE(const char *cFILE, const void *vClav);

 

 

Ejemplo:

 

 ...

 

 sDsF.sDk.li = li;

 SRRCAL_lLexi(&sDsF.sDk.li);

 

 sDsF.sDk.lj = lj;

 SRRCAL_lLexi(&sDsF.sDk.lj);

 lResul = SRRCW_DELETE("PRUEBASW", &sDsF);

 

 ...

 

 

Tras ejecutar la sentencia, el elemento queda borrado al reasignarse internamente a clave fuera de escala (*hival) tal como se indicó en el capítulo dedicado al funcionamiento interno de los ficheros virtuales.

 

Para depurar físicamente estos registros habría que emitir un SRRCW_REORGANIZE, pero esto sólo sería recomendable si el número de elementos gestionados fuese grande y el de eliminados relativamente también lo fuera.

 

                                                                                                     ________

 

 

Estas instrucciones son un extracto de la codificación de la rutina asociada al botón “DELETE” del programa PruebasW, que mostramos ahora al completo para verlas enmarcadas dentro de un contexto de programa:

 

//----------------------------------------------------------------------------------

// Función: PrPruebasD

//

// Descripción: Pruebas de SRRCW. Supresión de registros por clave

//

// Parámetros:

// (entrada) li : Nº de filas solicitado

//           lj : Nº de columnas solicitado

//

// Precondición: Debe haberse ejecutado PrPruebasW previamente
//

// Retorno: >0: Nº de ítems procesados

//         <=0: Errores

//----------------------------------------------------------------------------------

long PrPruebasD(long p_li, long p_lj)

{

 short int er = 0; // Control de invocaciones erróneas

 long lResul = 0;  // Control de resultados

 long lINDI = 0;   // Índice de posicionamiento

 long li = 0;      // Variable de for índice i

 long lj = 0;      // Variable de for índice j

 long lij = 0;     // Variable de for índice ij

 long lji = 0;     // Variable de for índice ji

 long p_lij = 0;   // Variable de retorno

 

 long lN = p_li * p_lj; // Nºtotal teórico i,j

 

 div_t div_result;      // Soporte de división con resto y cociente para la monitorización periódica

 

 

 // Inicio de Proceso

 

 er = PrMonitorW("SRRCW_DELETE(1)", 1, 1);// Graba registro monitorización DELETE 1 1

 if (er) return -1; // Control de parada externa desde MonitorW

 

 

 // Proceso. Paso 1. Borra registros pares

 

 lij = 0;

 

 for (li = 1; li <= p_li; ++li)

 for (lj = 1; lj <= p_lj; ++lj)

 {

  ++lij;

 

 

  // Borra 1 de cada 2 registros

 

  div_result = div(lij, 2);

  if (div_result.rem) continue;

 

 

  // Graba registro de monitorización y controla solicitud de parada externa

 

  div_result = div(lij, 551);

  if (!div_result.rem)

  {

   er = PrMonitorW("SRRCW_DELETE(1)", li, lj); // Graba registro monitorización

   if (er) return -lij; // Control parada externa

  }

 

 

  // Pasa clave de solicitud de borrado

 

  sDsF.sDk.li = li;

  SRRCAL_lLexi(&sDsF.sDk.li); // Ajuste de compatibilidad con memcmp en MsC++

 

  sDsF.sDk.lj = lj;

  SRRCAL_lLexi(&sDsF.sDk.lj);

 

 

  // Emite el borrado (Supone PrPruebasW previo)

 

  lResul = SRRCW_DELETE("PRUEBASW", &sDsF);

 

  if (!lResul)

  {

   return -(330000000 + li * 1000000 + lj);

  }

 

 }

 

 

 er = PrMonitorW("SRRCW_DELETE(1)", p_li, p_lj); // Graba registro monitorización final del paso 1

 

 if (er) return -1; // Control de parada externa desde MonitorW

 

 

 

 // Proceso. Paso 2. Restaura elementos pares suprimidos

 

 lij = 0;

 lji = lN + 1;

 

 for (li = 1; li <= p_li; ++li)

 for (lj = 1; lj <= p_lj; ++lj)

 {

  ++lij;

  --lji;

 

 

  // Sólo restaura elementos pares

 

  div_result = div(lij, 2);

  if (div_result.rem) continue;

 

 

  // Graba registro de monitorización y controla solicitud de parada externa

 

  div_result = div(lij, 551);

  if (!div_result.rem)

  {

   er = PrMonitorW("SRRCW_DELETE(2)", li, lj); // Graba registro de monitorización

   if (er) return -lij; // Control de parada externa

  }

 

 

  // Reconstruye elementos suprimidos. Parte de claves

 

  sDsF.sDk.li = li;

  SRRCAL_lLexi(&sDsF.sDk.li);

 

  sDsF.sDk.lj = lj;

  SRRCAL_lLexi(&sDsF.sDk.lj);

 

 

  sDsF.sDk01.lji = lji;

  sDsF.sDk01.EOR = '*';

  SRRCAL_lLexi(&sDsF.sDk01.lji);

 

 

  // Reconstruye elementos suprimidos. Parte de datos

 

  sDsF.sDd.lij = lij;

  sDsF.sDd.dij = (double) lij;

 

 

  // Graba registro reconstruido

 

  p_lij = SRRCW_WRITE("PRUEBASW", &sDsF);

  if (!p_lij)

  {

   return - (1000000000 + li * 1000000 + lj);

  }

 }

 

 

 er = PrMonitorW("SRRCW_DELETE(2)", p_li, p_lj); ); // Registro monitor final

 if (er) return –lij;

 

 return lij;

}

 

                                                                                                      ________

 

 

C.2.1.3.6 Funciones derivadas intrínsecamente del orden

 

 

C.2.1.3.6.1 Grupo posicionamiento (SETLL..)



Estas instrucciones son fundamentales porque establecen los puntos de partida de los bucles de proceso algorítmico.

 

 

Normalmente nos encontraremos con bucles del tipo:



-Bucles globales, de todo el fichero o desde un punto hasta el final



  READ con control de eof total

 

  SETLL o SETGTT + READ con control de eof total



 

-Y los bucles por clave de un interés algorítmico aun mayor si cabe

 

  SETLL + READE en una clave parcial con control de fin de fichero (eof) parcial

 

  SETGT + READPE en una clave parcial con control de comienzo de fichero (bof) parcial

 

 

Como vemos, el posicionamiento está íntimamente ligado a la lectura, por tanto los ejemplos se presentan al final de la definición de las instrucciones de posicionamiento y lectura por clave.

 

//-------------------------------------------------------------------------------------

// Función SRRCW_SETEQ

//

// Descripción: Determina la existencia en memoria de un ítem por clave igual,

// dejando a SRRCW preparado para responder a SRRCW_READE, etc

//

//

// Parámetros Formato completo

// (entrada) cFILE: Fichero solicitado

//           vCLVp: Clave (parcial) del ítem a situar

//           lLong: Longitud de clave significativa que se toma

//

//

// Parámetros Formato compacto

// (entrada) cFILE: Fichero solicitado

//           vCLVp: Clave (parcial) del ítem a situar

//

//

// Retorno

//          0: Error de proceso (No encontrado...)

//         >0: Índice en memoria-clave del ítem encontrado, en formato 1..N

//-------------------------------------------------------------------------------------

long SRRCW_SETEQ(const char *cFILE, const void *vCLVp, long lLong);

long SRRCW_SETEQ(const char *cFILE, const void *vCLVp);

 

 

//-------------------------------------------------------------------------------------

// Función SRRCW_SETGT

//

// Descripción: Situa en el índice de memoria-clave + próximo superior, dejando a

// SRRCW preparado para responder a SRRCW_READPE, etc

//

// Está pensado para seleccionar un subgrupo de ítems y recorrerlo de fin a

// principio, por ello devuelve la posición final del grupo. Si se desea

// dejar situado para leer el siguiente elemento, úsese SRRCW_SEGTT

//

//

// Parámetros Formato completo

// (entrada) cFILE: Fichero solicitado

//           vCLVp: Clave (parcial) del ítem a situar

//           lLong: Longitud de clave significativa que se toma

//

//

// Parámetros Formato compacto

// (entrada) cFILE: Fichero solicitado

//           vCLVp: Clave (parcial) del ítem a situar

//

//

// Retorno

//           0: Error de proceso (No encontrado...)

//         >0: Índice en memoria-clave + próximo inferior (+1), formato 1..N

//-------------------------------------------------------------------------------------

long SRRCW_SETGT(const char *cFILE, const void *vCLVp, long lLong);

long SRRCW_SETGT(const char *cFILE, const void *vCLVp);

 

 

//-------------------------------------------------------------------------------------

// Función SRRCW_SETGTT

//

// Descripción: Situa en el índice de memoria-clave + próximo superior, dejando a

// SRRCW preparado para responder a SRRCW_READE, etc

//

// La rutina deja situado el índice de lectura en el elemento siguiente

// al último que hubiera de clave igual a la indicada. Si por el contrario

// se desea seleccionar un subgrupo de ítems y recorrerlo de fin a principio,

// utilícese SRRCW_SETGT que, precisamente con esa intención, deja situado

// el índice al final de un grupo

//

//

// Parámetros Formato completo

// (entrada) cFILE: Fichero solicitado

//           vCLVp: Clave (parcial) del ítem a situar

//           lLong: Longitud de clave significativa que se toma

//

//

// Parámetros Formato compacto

// (entrada) cFILE: Fichero solicitado

//           vCLVp: Clave (parcial) del ítem a situar

//

//

// Retorno

//          0: Error de proceso (No encontrado...)

//         >0: Índice en memoria-clave + próximo inferior (+1), formato 1..N

//-------------------------------------------------------------------------------------

long SRRCW_SETGTT(const char *cFILE, const void *vCLVp, long lLong);

long SRRCW_SETGTT(const char *cFILE, const void *vCLVp);

 

 

//-------------------------------------------------------------------------------------

// Función SRRCW_SETLL

//

// Descripción: Sitúa en el índice de memoria-clave + próximo inferior (+ 1) o en el

// índice exacto del ítem, dejando a SRRCW preparado para responder a SRRCW_READE, etc

//

//

// Parámetros Formato completo

// (entrada) cFILE: Fichero solicitado

//           vCLVp: Clave (parcial) del ítem a situar

//           lLong: Longitud de clave significativa que se toma

//

//

// Parámetros Formato compacto

// (entrada) cFILE: Fichero solicitado

//           vCLVp: Clave (parcial) del ítem a situar

//

//

// Retorno

//           0: Error de proceso (No encontrado...)

//         >0: Índice en memoria-clave + próximo inferior (+1), formato 1..N

//-------------------------------------------------------------------------------------

long SRRCW_SETLL(const char *cFILE, const void *vCLVp, long lLong);

long SRRCW_SETLL(const char *cFILE, const void *vCLVp);

 

                                                                                                     ________

 

 

C.2.1.3.6.2 Grupo lectura (READ..)

 

Lectura secuencial básica, para bucles incondicionales completos de todo el fichero. Se presenta en un formato completo y otro reducido.

 

//-----------------------------------------------------------------

// FUNCION....: SRRCW_READ

//

// DESCRIPCION: Recupera un Ítem de Memoria Secuencialmente

// Como los elementos están ordenados por clave, una

// lectura secuencial devuelve los ítems ordenados.

//

//

// PARAMETROS.: Formato completo

//

// (entrada) cFILE : Fichero solicitado

//           iINDIp: Índice secuencial recuperación (IMPORTANTE: formato 1..N)

// (salida ) *vDato: Datos del Ítem

//           *vClav: Clave del Ítem

//

//

// PARAMETROS.: Formato compacto

//

// (entrada) cFILE : Fichero solicitado

//           iINDIp: Índice secuencial recuperación (IMPORTANTE: formato 1..N)

// (salida ) *vDato: Datos del Ítem

//

//

// RETORNO....:

//               0: Ítem leído satisfactoriamente

//               1: Error de Proceso (No encontrado(EOF), ...)

//

//-----------------------------------------------------------------

short int SRRCW_READ(const char *cFILE, long lINDIp, void *vDato, void *vClav);

short int SRRCW_READ(const char *cFILE, long lINDIp, void *vDato);

 

 

Ejemplo:

 

 ...

 er = SRRCW_READ("PRUEBASW", lij, &sDsF);

 ...

 

Se recupera el registro de posición lij en PRUEBASW según el diseño sDsF

 

 

Nota importante: La numeración de los registros se hace en base 1..N, no en base 0..N-1 para facilitar su uso desde ILE-RPG

 

 

 

Lectura por clave hacia adelante. Formatos completo y reducido.

 

//-------------------------------------------------------------------------------------

// Función SRRCW_READE

//

// Descripción: Recupera hacia adelante un ítem de memoria, manteniendo la clave igual

//

//

// Parámetros Formato completo

//

// (entrada) cFILE: Fichero solicitado

//           vCLVp: Clave (parcial) del ítem a situar

//           lLong: Longitud de clave significativa que se toma

// (salida) *vDato: Datos del ítem

//          *vClav: Valor de clave completo asociado

//

//

// Parámetros Formato compacto

//

// (entrada) lNIDp: Identificador de fichero virtual solicitado

//           vCLVp: Clave (parcial) del ítem a situar

//           lLong: Longitud de clave significativa que se toma

// (salida) *vDato: Datos del ítem

//

//

// Retorno

//           0: Error de proceso (No encontrado...)

//         >0: Índice en memoria-clave de ítem encontrado + 1, formato 1..N, posición de próxima lectura.

//

// Internamente se archiva en la variable global lINDI/W para uso interno posterior en +READE, etc.

//

//-------------------------------------------------------------------------------------

long SRRCW_READE(const char *cFILE, const void *vCLVp, long lLong, void *vDato, void *vClav);

long SRRCW_READE(const char *cFILE, const void *vCLVp, long lLong, void *vDato);

 

 

 

Lectura por clave hacia detrás. Formatos completo y reducido.

 

//-------------------------------------------------------------------------------------

// Función SRRCW_READPE

//

// Descripción: Recupera hacia detrás un ítem de memoria, manteniendo la clave igual

//

//

// Parámetros Formato completo

//

// (entrada) lNIDp: Identificador de fichero virtual solicitado

//           vCLVp: Clave (parcial) del ítem a situar

//           lLong: Longitud de clave significativa que se toma

// (salida) *vDato: Datos del ítem

//          *vClav: Valor de clave completo asociado

//

//

// Parámetros Formato compacto

//

// (entrada) cFILE: Fichero solicitado

//           vCLVp: Clave (parcial) del ítem a situar

//           lLong: Longitud de clave significativa que se toma

// (salida) *vDato: Datos del ítem

//

// Retorno

//           -1: Error de proceso (No encontrado...)

//         >=0: Índice en memoria-clave de ítem encontrado - 1, formato 1..N, posición de próxima lectura.

//

// Internamente se archiva en la variable global lINDI/W para uso interno posterior en +READPE, etc.

//

//-------------------------------------------------------------------------------------

long SRRCW_READPE(const char *cFILE, const void *vCLVp, long lLong, void *vDato, void *vClav);

long SRRCW_READPE(const char *cFILE, const void *vCLVp, long lLong, void *vDato);

 

 

 

Veamos un ejemplo conjunto de posicionamiento y lectura por clave hacia adelante

 

  . . .

 

 // Posiciona en la fila p_li

 

 sDsF.sDk.li = p_li;

 SRRCAL_lLexi(&sDsF.sDk.li);

 

 lINDI = SRRCW_SETLL("PRUEBASW", &sDsF, sizeof(long));

 

 

 // Lee todos los ítems de la fila p_li

 

 for (lj = 1; lj <= p_lj; ++lj)

 {

  lINDI = SRRCW_READE("PRUEBASW", &sDsF, sizeof(long), &sDsF);

  . . .

 }

 

 

 

 Veamos un ejemplo conjunto de posicionamiento y lectura por clave hacia detrás

 

 // Posiciona al final de la fila p_li

 

 sDsF.sDk.li = p_li;

 SRRCAL_lLexi(&sDsF.sDk.li);

 

 lINDI = SRRCW_SETGT("PRUEBASW", &sDsF, sizeof(long));

 

 for (lj = p_lj; lj >= 1; --lj)

 {

  lINDI = SRRCW_READPE("PRUEBASW", &sDsF, sizeof(long), &sDsF);

  . . .

 }

 

 . . .

 

Estos ejemplos se integran en la rutina PrPruebasR de PruebasW, que se invoca al pulsar el botón “Read”, y que se lista ahora para verlos dentro de un contexto de programa

 

//-----------------------------------------------------------------------------------

// Función: PrPruebasR

//

// Descripción: Pruebas de SRRCW. Lectura secuencial READ, READE, READPE

//

//

// Precondición: Debe haberse ejecutado PrPruebasW previamente
//

// Parámetros:

// (entrada) li : Nº de filas solicitado

//           lj : Nº de columnas solicitado

//

// Retorno: >0: Nº de ítems generados

//         <=0: Errores

//-----------------------------------------------------------------------------------

long PrPruebasR(long p_li, long p_lj)

{

 short int er = 0; // Control de invocaciones erróneas

 long lINDI = 0;   // Índice de posicionamiento

 long li = 0;      // Variable de for índice i

 long lj = 0;      // Variable de for índice j

 long lij = 0;     // Variable de for índice ij

 long lji = 0;     // Variable de for índice ji

 long p_lij = 0;   // Variable de retorno

 

 long lN = p_li * p_lj; // Nºtotal teórico i,j

 

 div_t div_result;      // Soporte de división con resto y cociente para la monitorización periódica

 

 

 // Inicio de Proceso

 

 er = PrMonitorW("SRRCW_READE", p_li, 1); // Graba registro monitor READE 1 1

 if (er) return -1; // Control de parada externo

 

 

 // Proceso – Paso 1. Lectura por = hacia delante en fila i

 

 li = p_li;

 lij = (p_li - 1) * p_lj;

 

 

 // Pasa valor de clave de posicionamiento

 

 sDsF.sDk.li = p_li;

 SRRCAL_lLexi(&sDsF.sDk.li); // Ajuste de compatibilidad con memcmp en MsC++

 

 

 // Inicializa el resto de la estructura de soporte

 

 sDsF.sDk.lj = 0;

 sDsF.sDk01.lji = 0;

 sDsF.sDk01.EOR = '*';

 

 sDsF.sDd.lij = 0;

 sDsF.sDd.dij = 0.0;

 

 

 // Emite el posicionado al comienzo de la fila i

 

 lINDI = SRRCW_SETLL("PRUEBASW", &sDsF, sizeof(long));

 

 for (lj = 1; lj <= p_lj; ++lj)

 {

  ++lij;

 

 

  // Ejecuta la operación de lectura por igual hacia delante de la fila i

 

  lINDI = SRRCW_READE("PRUEBASW", &sDsF, sizeof(long), &sDsF);

 

 

  // Control de EoF inesperado

 

  if (!lINDI)

  {

   return -(110000000 + li * 1000000 + lj);

  }

 

 

  // Control de consistencia con PrPruebasW

 

  if (lij != sDsF.sDd.lij)

  {

   return -(220000000 + li * 1000000 + lj);

  }

 }

 

 

 // Proceso - Paso 2. Lectura por = hacia detrás

 

 er = PrMonitorW("SRRCW_READPE", p_li, p_lj); // Emite monitorización READPE inicial

 if (er) return -1; // Control de parada externa

 

 

 // Pasa valor de clave de posicionamiento

 

 sDsF.sDk.li = p_li;

 SRRCAL_lLexi(&sDsF.sDk.li);

 

 

 // Inicializa el resto de la estructura de soporte

 

 sDsF.sDk.lj = 0;

 sDsF.sDk01.lji = 0;

 sDsF.sDk01.EOR = '*';

 

 sDsF.sDd.lij = 0;

 sDsF.sDd.dij = 0.0;

 

 

 // Emite el posicionado al final de la fila i

 

 lINDI = SRRCW_SETGT("PRUEBASW", &sDsF, sizeof(long));

 

 ++lij;

 

 for (lj = p_lj; lj >= 1; --lj)

 {

  --lij;

 

 

  // Ejecuta la operación de lectura por igual hacia detrás de la fila i

 

  lINDI = SRRCW_READPE("PRUEBASW", &sDsF, sizeof(long), &sDsF);

 

 

  // Control de EoF inesperado

 

  if (lINDI<0)

  {

   return -(110000000 + li * 1000000 + lj);

  }

 

 

  // Control de consistencia con PrPruebasW

 

  if (lij != sDsF.sDd.lij)

  {

   return -(220000000 + li * 1000000 + lj);

  }

 }

 

 

 

 // Proceso – Paso 3. Lectura secuencial

 

 er = PrMonitorW("SRRCW_READ", 1, 1); // Emite monitorización READ 1 1

 if (er) return -1; // Control de parada externa

 

 lij = 0;

 

 for (li = 1; li <= p_li; ++li)

 for (lj = 1; lj <= p_lj; ++lj)

 {

  ++lij;

 

 

  // Emite monitorización periódica, controlando solicitud de parada externa

 

  div_result = div(lij, 551);

  if (!div_result.rem)

  {

   er = PrMonitorW("SRRCW_READ", li, lj);

   if (er) return -lij;

  }

 

  er = SRRCW_READ("PRUEBASW", lij, &sDsF);

 

 

  // Control de EoF prematuro

 

  if (er)

  {

   return -(330000000 + li * 1000000 + lj);

  }

 

 

  // Control de consistencia con PrWriteW

 

  SRRCAL_lLexi(&sDsF.sDk.li);

  SRRCAL_lLexi(&sDsF.sDk.lj);

 

  if (lij != sDsF.sDd.lij)

  {

   return -(440000000 + li * 1000000 + lj);

  }

 }

 

 // Emite registro de monitorización final

 

 er = PrMonitorW("SRRCW_READ", p_li, p_lj);

 if (er) return –lij;

 

 return lij;

}

 

                                                                                                     ________

 

 

C.2.1.3.7 Extensiones de base de datos. CPY y DUP

 

 

// Copia datos de un fichero virtual a otro

 

//--------------------------------------------------------------------------------------

//

// Función: SRRCW_CPY

//

// Descripción: Copia de registros. Deben proporcionarse nombres de ficheros "físicos"

// base, aunque el proceso duplicará las operaciones a la BD relacionada

//

// Parámetros:

// (entrada) cORG: Nombre del fichero físico origen

//           cDES: Nombre del fichero físico destino

//           iREP: 0=Copia con adicción simple (COPY *ADD)

//                 1=Copia con borrado previo (COPY *REPLACE) [*DFT]

//                 2=Copia con eliminación previa de registros duplicados en destino (COPY *MERGE)

//

// Retorno:

//         >=0: Contador de registros copiados

//           <0: Error de proceso

//--------------------------------------------------------------------------------------

long SRRCW_CPY(const char *cORG, const char *cDES, short int iREP)

long SRRCW_CPY(const char *cORG, const char *cDES); [iREP = 1]

 

 

El parámetro iREP se diseño inicialmente como una marca (0/1) para indicar si se debía limpiar el fichero de destino previamente a efectuar la copia de datos.

 

Posteriormente se implementó el valor 2 que indica que se deben copiar los datos reemplazando los preexistentes con la misma clave si los hubiera.

 

 

Ejemplo:

 

 ...

 

 lNCPY = SRRCW_CPY("PRUEBASW", "PRUEBASWCPY");

 

 ...

 

 

Al ejecutar esta instrucción, se copian los datos del fichero PRUEBASW al fichero PRUEBASWCPY; además, previamente, se limpia el fichero destino.

 

El nº de registros copiado se registra en lNCPY.

 



 

// Duplicación de bases de datos virtuales

 

//--------------------------------------------------------------------------------------

//

// Función: SRRCW_DUP

//

// Descripción: Duplica una base de datos virtual

//

// Parámetros:

// (entrada) cORG: Nombre del fichero origen

//           cDES: Nombre del fichero destino

//

// Retorno:

//  0: Error de proceso

// >0: NID de cDES

//

//--------------------------------------------------------------------------------------

long SRRCW_DUP(const char *cDES, const char *cORG);

 

 

Esta instrucción duplica la base de datos origen en una nueva.

 

No debe existir previamente. Si se precisa, utilice SRRCW_ERASE antes, como en el ejemplo que se presenta:

 

 ...

 

 // Elimina contenido anterior y duplica el nuevo

 

 er = SRRCW_ERASE("PRUEBASWCPY");

 

 lNID = SRRCW_DUP("PRUEBASW", "PRUEBASWCPY");

 if (!lNID) return 0;

 ...

 

 

Aquí se elimina primero la base de datos virtual PRUEBASWCPY

                                                 |_ PRUEBASWCPY01

 

y a continuación se duplica PRUEBASW      en   PRUEBASWCPY

                            |_ PRUEBASW01      |_ PRUEBASWCPY01

 

 

La instrucción supone que se especifican los nombres de los ficheros físicos base a duplicar, entonces explora dependencias y las duplica en destino, incluyendo datos.

 

                                                                                                      ________

 

C.2.1.3.8 Persistencia de datos. RSTF y SAVF

 

 

// Salvado a fichero físico

 

//--------------------------------------------------------------------------------------

//

// Función: SRRCW_SAVF

//

// Descripción: Salva registros a soporte físico cFILE.DAT

//

// Parámetros:

// (entrada) cFILE: Nombre del fichero origen

//            iDES: 0/1 Desglosar clave y datos. 0 <=> Clave y datos solapados (Situación habitual)

//

// Retorno:

//         >=0: Contador de registros copiados

//           <0: Error de proceso

//

//--------------------------------------------------------------------------------------

long SRRCW_SAVF(const char *cFILE, short int iDES);

long SRRCW_SAVF(const char *cFILE); [iDES=0]

 

 

 

// Restauración desde fichero físico

 

//--------------------------------------------------------------------------------------

//

// Función: SRRCW_RSTF

//

// Descripción: Restaura salva de registros desde soporte físico cFILE.DAT

//

// Parámetros:

// (entrada) cFILE: Nombre del fichero destino

//            iDES: 0/1 Desglosar clave y datos. 0 <=> Clave y datos solapados (Situación habitual)

//

// Retorno:

//         >=0: Contador de registros copiados

//          <0: Error de proceso

//

//--------------------------------------------------------------------------------------

long SRRCW_RSTF(const char *cFILE, short int iDES);

long SRRCW_RSTF(const char *cFILE); [iDES=0]

 

 

Ejemplos:

 

lNCPY = SRRCW_SAVF("PRUEBASW");

lNCPY = SRRCW_RSTF("PRUEBASW");

 

En estas instrucciones, se salva PRUEBASW a PRUEBASW.DAT y luego se restaura, siendo lNCPY el nº de registros salvados/restaurados.

 

Se indica que no se desea desglosar clave y datos si no que se salvan contiguamente, será lo habitual, salvo casos especiales en que se utilicen lógicos.

 

Los datos se archivan en formato binario (internamente se ejecuta fopen(“PRUEBASW”, "wb"))

 

Los nombres que se proporcionan se normalizan utilizando SRRCW_NAME (que se presenta más adelante) y se le agregará el terminador .DAT

 

                                                                                                     ________

 

 

C.2.1.3.9 Grupo informativo y de control. INF, NAME y NID

 

 

// Recuperación de estadísticos base de un fichero

 

//-------------------------------------------------------------------------------------

// FUNCION....: SRRCW_INF

//

// DESCRIPCION: Recupera información estadística de un fichero

//

// PARAMETROS.:

// (entrada) cFILE: Nombre de fichero solicitado

// (salida ) iDIMC: Tamaño clave

//           lDimD: Tamaño datos

//          lNÍTEM: Nºde ítems archivados (, de los que)

//          lBAJAS: (es el)Nºde ítems que son baja (y, por otro lado, )

//          lNIDD : (es el)Nºde ítems que aún pueden agregarse

//

// RETORNO....:

// 0: Información recuperada satisfactoriamente

// 1: Error de Proceso (No encontrado(EOF), ...)

//

//-------------------------------------------------------------------------------------

short int SRRCW_INF(const char *cFILE, int *iDimC, long *lDimD, long *lNÍTEM, long *lBAJAS, long *lNIDD);

 

Ejemplo:

 

 ...

 

 er = SRRCW_INF("PRUEBASW", &m_iDimC, &m_lDimD, &m_lNÍTEM, &m_lBAJAS, &lNIDD);

 

 m_lNETO = m_lNÍTEM - m_lBAJAS;

 

 ...

 

 

En éste ejemplo SRRCW_INF se emplea para obtener el número de ítems del fichero "PRUEBASW", y también el número neto depurado de bajas.

 

Este número permite acceder directamente al último registro del fichero en el orden de la vía de acceso, como sigue:

 

 ...

 

 er = SRRCW_READ(“PRUEBASW”, m_lNETO, &sDsF);

 

 ...

 

 

//-------------------------------------------------------------------------------------

//

// Función SRRCW_NAME

//

// Descripción: Normalizador de nombres a longitud de 32+1(terminador)

//               (Depura recepción de parámetro recibido desde literal con terminador prematuro)

//

// Parámetros

// (entrada) cFILE Cadena nombre origen

//

// Retorno Nombre depurado, *BLANKS si error

//

//-------------------------------------------------------------------------------------

char* SRRCW_NAME(const char *cFILE);

 

SRRCW_NAME normaliza nombres para garantizar la misma longitud efectiva comparable de los mismos. Ofrece también una mínima protección a su edición involuntaria, cosa desaconsejable al tratarse de un fichero binario, al incluir blancos de cola en el nombre.

 

Así por ejemplo, si recibe

 

"NOMBRE\0" SRRCW_NAME lo convierte al valor normalizado

"NOMBRE                        \0" (Tamaño 33 = 32 Como cadena de caracteres + 1 erminador \00)

123456789012345678901234567890123 En base 1

012345678901234567890123456789012 En base 0

 

Todas las rutinas que reciben nombre de fichero la invocan como primera tarea para garantizar comparaciones de nombres homogéneas.

 

 

//--------------------------------------------------------------------------------------

//

// Función SRRCW_NID

//

// Descripción Recupera el NID asociado a un fichero en memoria

//

// Parámetros

//

// (entrada) cFILE: Nombre de fichero

//

// Retorno

//           0: Error de proceso

//         >0: NID solicitado

//

//--------------------------------------------------------------------------------------

long SRRCW_NID(const char *cFILE);

 

La rutina devuelve el número interno asignado a un fichero.

 

Indirectamente permite conocer si un fichero ya se ha creado anteriormente, pues si devuelve un valor nulo es señal de que el nombre de fichero todavía no se ha utilizado en la aplicación.

 

 

 

//--------------------------------------------------------------------------------------

//

// Función: SRRCW_NIDFILE

//

// Descripción: Recupera el nombre asociado un NID

//

// Parámetros:

// (entrada) lNID: Identificador solictado

//

// Retorno:

//    Null : No encontrado

// ó Nombre: Nombre buscado

//

//--------------------------------------------------------------------------------------

char* SRRCW_NIDFILE(long P_lNID);

 

De forma recíproca a como hace la rutina anterior, esta rutina auxiliar devuelve el nombre asociado a un identificador, o un puntero nulo en caso de no haber correspondencia.

 

Puede no encontrarse por ser una numeración que exceda las asignadas, o por tratarse de un identificador suprimido, o por ser un identificador reservado para uso interno en la generación de los propios ficheros de soporte de relaciones entre físicos y lógicos, etc.

 

                                                                                                     ________

 

 

C.2.1.3.10 Pilas y colas

 

La emulación de filas y colas se utiliza generando unos archivos especiales en los que las claves se asignan automáticamente en función del orden de grabación.

 

En las colas se emplea el orden FIFO (First input, first output; primero en llegar, primero en salir) como en las colas de los supermercados y en las pilas el LIFO (Last input, first output; último en llegar, primero en salir) como en las pilas de platos.

 

Para concretar con un ejemplo, supongamos que en PruebasW introducimos en la ventana de apilar de un lado, así como en la ventana de encolar de otro, utilizando los botones Apilar & Encolar, los valores 111, 222, 333, 444 hasta obtener la imagen que se muestra:

 

 

Si ahora desapilamos, nos reaparece 444; por el contrario si desencolamos nos aparecería 111.

 

 

Si repetimos la operación obtendríamos 333 al desapilar y 222 al desencolar como se muestra en la figura

 

 

 

 

Las instrucciones que soportan la operativa de pilas y colas se presentan a continuación

 

                                                                                                     ________

 

C.2.1.3.10.1 Grupo emulación pilas (LIFO)

 

//-------------------------------------------------------------------------------------

//

// Función SRRCW_FIFO_NEW

//

// Descripción Genera una cola (FIFO)

//

//

// Parámetros Formato completo

//

// (entrada) cFIFO Nombre de cola asociada

//           lDimD Dimensión de datos a guardar en la cola

//        lMaxNreg Nº Máximo de registros a guardar

//

//

// Parámetros Formato compacto

//

// (entrada) cFIFO Nombre de cola asociada

//           lDimD Dimensión de datos a guardar en la cola

//

// Retorno

//           0 Error de proceso

//         >0 Nid asociado

//

//--------------------------------------------------------------------------------------

long SRRCW_FIFO_NEW(const char *cFIFO, long lDimD, long lMaxNreg);

long SRRCW_FIFO_NEW(const char *cFIFO, long lDimD);

 

 

Ejemplo:

 

La instrucción

 

 

   lNID_Cola = SRRCW_FIFO_NEW("COLA", 80);

 

 

genera una cola de nombre "COLA" y longitud 80.

 

 

Si la cola existiera previamente, la instrucción la regeneraría limpiando su contenido.

 

 

//--------------------------------------------------------------------------------------

//

// Función SRRCW_FIFO_READ

//

// Descripción Lee un ítem de la cola

//

//

// Parámetros Formato completo

//

// (entrada) cFIFO Nombre de cola

// (salida)  vDato Datos del ítem

// (entrada) cOpci Opción 0/1 borrar elemento leído

//

//

// Parámetros Formato compacto

//

// (entrada) cFIFO Nombre de cola

// (salida)  vDato Datos del ítem

//

// Retorno

//           0 OK

//         >0 Error de proceso

//--------------------------------------------------------------------------------------

short int SRRCW_FIFO_READ(const char *cFIFO, void *vDato, char cOp);

short int SRRCW_FIFO_READ(const char *cFIFO, void *vDato);

 

 

La instrucción

 

 

   lResu = SRRCW_FIFO_READ("COLA", cCola);

 

 

leería un ítem de la cola "COLA"

 

 

Como "COLA" es en si mismo un fichero, se pueden emitir sobre el operaciones generales como en

 

 

   er = SRRCW_INF("COLA", &iDimC, &lDimD, &lNÍTEM, &lBAJAS, &lNIDD);

 

   m_lNETOC = lNÍTEM - lBAJAS;

 

 

en donde obtendríamos el tamaño efectivo actual de "COLA"

 

 

//-------------------------------------------------------------------------------------

// Función SRRCW_FIFO_WRIT

//

// Descripción Guarda un ítem en la cola

//

// Parámetros

// (entrada) cFIFO Nombre de la cola

//           vDato Datos a guardar

//

// Retorno

//          0 Error de proceso

//         >0 Índice del ítem guardado

//

//--------------------------------------------------------------------------------------

long SRRCW_FIFO_WRIT(const char *cFIFO, const void *vDato);

 

 

Así por ejemplo, la instrucción

 

 

   lResu = SRRCW_FIFO_WRIT("COLA", cCola);

 

 

grabaría el ítem cCola en la cola "COLA"

                                                                                                     ________

 

C.2.1.3.10.2 Grupo emulación colas (FIFO)

 

Las instrucciones asociadas son las mismas que se han presentado antes para las colas sustituyendo el término FIFO por LIFO.

 

//-------------------------------------------------------------------------------------

//

// Función SRRCW_LIFO_NEW

//

// Descripción Genera una pila (LIFO)

//

//

// Parámetros Formato completo

//

// (entrada) cLIFO Nombre de pila asociada

//           lDimD Dimensión de datos a guardar en la cola

//        lMaxNreg NºMáximo de registros a guardar

//

//

// Parámetros Formato compacto

//

// (entrada) cLIFO Nombre de pila asociada

//           lDimD Dimensión de datos a guardar en la cola

//

// Retorno

//  0 Error de proceso

// >0 Nid asociado

//

//--------------------------------------------------------------------------------------

long SRRCW_LIFO_NEW(const char *cFIFO, long lDimD, long lMaxNreg);

long SRRCW_LIFO_NEW(const char *cFIFO, long lDimD);

 

 

//--------------------------------------------------------------------------------------

//

// Función SRRCW_LIFO_READ

//

// Descripción Lee un ítem de la pila

//

//

// Parámetros Formato completo

//

// (entrada) cLIFO Nombre de pila

// (salida)  vDato Datos del ítem

// (entrada) cOpci Opción 0/1 borrar elemento leído

//

//

// Parámetros Formato compacto

//

// (entrada) cLIFO Nombre de pila

// (salida)  vDato Datos del ítem

//

// Retorno

//           0 OK

//         >0 Error de proceso

//--------------------------------------------------------------------------------------

short int SRRCW_LIFO_READ(const char *cFIFO, void *vDato, char cOpci);

short int SRRCW_LIFO_READ(const char *cFIFO, void *vDato);

 

 

//-------------------------------------------------------------------------------------

// Función SRRCW_LIFO_WRIT

//

// Descripción Guarda un ítem en la pila

//

// Parámetros

// (entrada) cLIFO Nombre de la pila

//           vDato Datos a guardar

//

// Retorno

//           0 Error de proceso

//         >0 Idice del ítem guardado

//

//--------------------------------------------------------------------------------------

long SRRCW_LIFO_WRIT(const char *cFIFO, const void *vDato);



 

                                                                                                     ________



 

 

El código completo del programa PruebasW se encuentra en el apéndice

"C5 Relación de programas de muestra desarrollados en el libro"



 

                                                                                                     ________