Serie ficheros virtuales

 

javascript  Ficheros virtuales

 

 

 

 

La conversión de w_ficherosvirtuales_com

 

1 Introducción

2 Lista de prototipos

3 Generación de un fichero virtual. La función NEW

4 Arquetipo de las funciones clásicas de SRRCM en SRRCW. La función READ

5 Funciones específicas por la aparición de lógicos. La función CRTLF

6 La función DELETE

7 Las operaciones globales. CPY y DUP

 

                                                                                                  _________

 

 

1 Introducción

 

 

El objeto w_ficherosvirtuales_com integra la conversión de los módulos C-ANSI SRRCU, SRRCM, SRRCN y SRRCW originales encapsulándolos como un objeto único que exporta como métodos las funciones que SRRCW declaraba como accesibles dejando el resto de funciones como privativas al objeto.

 

Para poder hacer esto se siguen las dos etapas que se han apuntado en los capítulos anteriores: La conversión de los procedimientos y su encapsulación.

 

Los epígrafes posteriores se dedicarán al detalle de la conversión de los procedimientos. El paso final de la encapsulación es tan sencillo como definir un objeto en cuyo cuerpo principal se incluyan los procedimientos y al final los métodos exportados.

 

 

Así, si sólo dejáramos la función SRRCW_NEW el resultado sería:

 

function w_ficherosvirtuales_com ()

{

 ...

 

  function W_NEW(cFILE, iDimC, lDimD) { . . . }

 

 ...

 

        this.NEW = W_NEW;

 

 ...

}

 

 

                                                                                                  _________

 

 

2 Lista de prototipos (Originales y convertidos)

 

 

Sigue una lista de los prototipos originales en C ANSI y su conversión a javascript. Para más detalle, acudir a los epígrafes dedicados a la explicación detallada de la conversión de cada función. También puede acudirse al capitulo homólogo del blog original de la serie dedicado al lenguaje C.

 

 

 

 

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

// Funciones de gestión de objetos

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

 

 

// Crear. Limpia datos previos si existieran

 

 

Prototipos originales en C ANSI:

 

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

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

 

 

Prototipo convertido a javascript

 

  function W_NEW(cFILE, iDimC, lDimD)

 

 

Declaración de exportación asociada (Como todas son iguales, sólo se explicita esta primera)

 

   this.NEW = W_NEW;

 

 

 

 

// Crear. Sin limpiar datos previos

 

 

Prototipos originales en C ANSI:

 

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

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

 

 

Prototipo convertido a javascript

 

   function W_NOW(cFILE, iDimC, lDimD)

 

 

 

 

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

 

 

Prototipo original en C ANSI:

 

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

 

 

Prototipo convertido a javascript

 

  function W_CRTLF(cLF, cPF, iKPOS, iKLEN)

 

 

 

 

// Vaciado de datos

 

 

Prototipos originales en C ANSI:

 

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

  short int SRRCW_CLRF(const char *cFILE);

 

 

Prototipo convertido a javascript

 

  function W_CLRF(cFILE, lNBAJp) 

 

 

 

// Eliminación completa

 

 

Prototipo original en C ANSI:

 

  short int SRRCW_ERASE(const char *cFILE);

 

 

Prototipo convertido a javascript

 

  function W_ERASE(cFILE)

 

 

 

// Cierre total

 

 

Prototipo original en C ANSI:

 

  short int SRRCW_CLOSE(void);

 

 

Prototipo convertido a javascript

 

  function W_CLOSE() 

                                                                                                  _________

 

 

 

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

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

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

 

// Grupo CHAIN

 

Prototipos originales en C ANSI:

 

  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);

 

 

Prototipos convertidos a javascript

 

  function W_CHAIN(cFILE, vClav, vDato, lLong)

  function W_CHAINr(cFILE, vClav, vDato)

  function W_VER(cFILE, vClav)

 

 function W_PARM_READ(sNAME, vDato)    [Función añadida. Lee de forma asíncrona el valor de un parámetro. También podría añadirse al SRRCW original]

 

 

// Grupo WRITE

 

Prototipos originales en C ANSI:

 

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

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

  

 

Prototipos convertidos a javascript

 

  function W_WRITE(cFILE, vClav, vDato)

 

   function W_PARM_WRITE(sNAME, vDato)  [Función añadida. Graba el valor de un parámetro para su uso asíncrono. También podría añadirse al SRRCW original]

 

 

 

// Funciones derivadas directas

 

// UPDATE

 

Prototipos originales en C ANSI:

 

  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);

   

 

Prototipos convertidos a javascript

 

   function W_UPDATE(cFILE, vClav, vDato, lLong)

   function W_UPDATEr(cFILE, vClav, vDato)

 

 

// Funciones derivadas intrínsicamente del orden

 

// Grupo DELETE

 

Prototipos originales en C ANSI:

 

  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);

   

 

Prototipos convertidos a javascript

 

   function W_DELETE(cFILE, vClav, lLong)

   function W_DELETEr(cFILE, vClav) 

 

   function W_REORGANIZE(cFILE, lNBAJp)

 

 

// Grupo Posicionamiento

 

Prototipos originales en C ANSI:

 

  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);

 

 

Prototipos convertidos a javascript

 

   function W_SETEQ(cFILE, vCLVp, lLong)

   function W_SETGT(cFILE, vCLVp, lLong)

   function W_SETGTT(cFILE, vCLVp, lLong)

   function W_SETLL(cFILE, vCLVp, lLong)

 

 

// Grupo READ

 

Prototipos originales en C ANSI:

 

  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);

 

 

Prototipos convertidos a javascript

 

   function W_READ(cFILE, lINDIp, vDato, vClav)

   function W_READE(cFILE, vCLVp, lLong, vDato, vClav)

   function W_READPE(cFILE, vCLVp, lLong, vDato, vClav)

 

                                                                                                  _________

 

 

 

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

// Extensión de base de datos

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

 

// Copia de datos

 

Prototipos originales en C ANSI:

 

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

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

 

 

Prototipo convertido a javascript

 

   function W_CPY(cORG, cDES, iREP)

 

 

// Duplicacion de bases de datos virtuales

 

Prototipo original en C ANSI:

 

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

 

 

Prototipo convertido a javascript

 

   function W_DUP(cORG, cDES)

        

                                                                                                  _________

 

 

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

// Grupo informativo y de control

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

 

Prototipos originales en C ANSI:

 

  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);

 

 

Prototipos convertidos a javascript

 

   function W_INF(cFILE, iDimCp, lDimDp, lNITEMp, lBAJASp)

   function W_NAME(cFILE)

   function W_NID(cFILE)

   function W_NIDFILE(P_lNID

 

                                                                                                  _________

 

 

 

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

// Persistencia de datos

//

//  No se han implementado versiones similares en javascript

//

//      ( Involucrarían salvado/restauración a cookie lo que no puede garantizarse de forma genérica )

//

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

 

// 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);

 

 

                                                                                                  _________

 

 

 

Comencemos ahora a ver los extractos de la codificación principal de las funciones de SRRCW y su conversión a w_ficherosvirtuales_com:

 

 

                                                                                                  _________

 

 

3 Generación de un fichero virtual. La función NEW

 

La función NEW tiene el siguiente prototipo original en C ANSI:

 

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

// 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: Dimensión 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: Dimensión 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)

 

 

Y su código esencial se resume así:

 

...

 

// Asigna un nuevo identificador de tipo SRRCM

 

lNIDw = SRRCM_NEWC(iDimC, lDimD, lMaxNreg);

 

 

// graba enlace nombre-identificador

 

lresul = SRRCM_WRITE(lNIDf, cFILEw, &lNIDw);

 

return lNIDw;

 

...

                                                                                                  _________

 

 

 

La conversión a javascript consta de dos pasos. Primero la conversión bruta del procedimiento y segundo su encapsulación en el objeto w_ficherosvirtuales_com:

 

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

// FUNCION....: W_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: Dimensión 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: Dimensión 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)                   

//                                                                

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

function W_NEW(cFILE, iDimC, lDimD)

{

 var cFILEw = " "; // Aux.paso de nombre

 var lNIDw = 0;    // Nid asociado a un nombre

 var lresul = 0;   // Control resultado invocaciones

 var lDimDw = 0;   // Paso opcional de lDimD

 

 

 // Paso de parámetros opcionales

 

 lDimDw = iDimC;

 if (lDimD > 0) lDimDw = lDimD;

 

 

 // Asigna NIDf para enlace entre nombres de fichero y nid de los mismos

 

 if (!lNIDf) lNIDf = M_NEW(lStandarName, 10);

 if (!lNIDf) return 0;

 

 

 // Normaliza nombre

 

 cFILEw = W_NAME(cFILE);

 

 

 // Asigna NID pre-existente del file solicitado

 

 lNIDw = W_NID(cFILEw);

 if (lNIDw)

 {

 

  // Inz datos pre-existentes

 

  lresul = W_CLRF(cFILEw);

 

 

  // Graba enlace nombre-nid

 

  lresul = M_UPDATE(lNIDf, cFILEw, (lNIDw + lKTE).toString());

  if (!lresul) return 0;

 }

 else

 {

 

  // Asigna nuevo nid

 

  lNIDw  = M_NEW(iDimC, lDimDw);

  if (!lNIDw) return 0;

 

 

  // Graba enlace nombre-nid

 

  lresul = M_WRITE(lNIDf, cFILEw, (lNIDw + lKTE).toString());

  if (!lresul) return 0;

 }

 

 return lNIDw;

}

 

                                                                                                  _________

 

 

 

Esta función se encapsula en el objeto w_ficherosvirtuales_com especificando al final del módulo

 

. . .

 

     this.NEW = W_NEW;

 

. . .

                                                                                                  _________

 

 

 

Se genera pues un fichero con M_NEW de identificador “lNIDw”. Este identificador se guarda en otro fichero virtual de uso interno “lNIDf” que está encargado de archivar las relaciones entre los identificadores numéricos generados y los nombres de usuario.

 

 

El sistema funciona entonces como sigue

 

Al abrir la aplicación se crea el fichero “lNIDf”, pongamos por caso lNIDf = 1, en que las claves serán los nombres asignados por el usuario a los ficheros que se generen, y en donde las claves las compondrán los identificadores de tipo SRRCM correspondientes.

 

Los diversos nombres que se fueran proporcionando se registrarían en el fichero de relaciones de la forma que se indica en la siguiente tabla ejemplo tipo:

 

 

 

 

 

Fichero de relaciones que se graba en el identificador de fichero 1

Nombre dado

Identificador generado

Clave

Datos

 

 

 

 

(Relaciones)

1

-

-

 

 

 

 

EJEMPLO”

2

EJEMPLO

2

ARCHIVO”

3

ARCHIVO

3

TRABAJO”

         4

TRABAJO

   4

. . .

 

. . .

 

NOMBRE”

11

NOMBRE

11

FICHERO”

12

FICHERO

12

TEMPORAL”

        13

TEMPORAL

  13

. . .

 

. . .

 

 

 

                                                                                                  _________

 

 

Entonces cada vez que se vaya a utilizar un fichero, pongamos por caso “NOMBRE”, se accede a esta tabla y se toma su identificador, “11”, que es el que finalmente se utiliza para acceder a los datos grabados con él en la aplicación núcleo SRRCM.

 

                                                                                                  _________

 

 

 

4 Arquetipo de las funciones clásicas de SRRCM en SRRCW. La función READ

 

Cada una de las funciones de SRRCW homónimas a las de SRRCM consiste básicamente en una llamada a una rutina que recupera el identificador asociado (de tipo SRRCM) a un nombre de usuario (de tipo SRRCW) y a continuación de la emisión de la operación solicitada (traducida a tipo SRRCM) sobre el fichero al que apunte el identificador extraído.

 

Este esquema se mantiene en w_ficherosvirtuales_com. El método READ ejecuta internamente la función W_READ, que es un interfaz para usar con nombre de fichero a la función M_READ, más interna, que utiliza identificadores numéricos en lugar de nombres.

 

Veámoslo con la operación READ, de prototipo original en C:

 

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

// 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: Indice secuencial recuperación

//                   (IMPORTANTE: formato 1..N)

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

//           *vClav: Clave del Ítem

//

//

// PARAMETROS.: Formato compacto

//

// (entrada) cFILE : Fichero solicitado

//           iINDIp: Indice secuencial recuperación

//                   (IMPORTANTE: formato 1..N)

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

//

//

// RETORNO....: Indicador de error

//              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)

 

 

Y cuyas sentencias principales se resumen en:

 

...

 

// Identificador de tipo SRRCM del fichero solicitado

 

lNIDw = SRRCW_NID(cFILEw);

 

 

// Proceso

 

return SRRCM_READC(lNIDw, lINDIp, vDato, vClav);

 

...

 

                                                                                                  _________

 

 

Mientras que la función convertida a javascript tiene el código siguiente:

 

/*-----------------------------------------------------------------*/

/* FUNCION....: W_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: Indice secuencial recuperación                */

/*                   (IMPORTANTE: formato 1..N)                    */

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

/*           *vClav: Clave del ítem (opcional)                     */

/*                                                                 */

/* RETORNO....:                                                    */

/*                 0: Item leído satisfactoriamente                */

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

/*                                                                 */

/*-----------------------------------------------------------------*/

function W_READ(cFILE, lINDIp, vDato, vClav)

 

 

Y cuyas sentencias principales se resumen en:

 

...

 

 

  // Identificador de tipo M del fichero solicitado

 

  lNIDw = W_NID(cFILEw);

 

 

 

  // Proceso

 

  return M_READ(lNIDw, lINDIp, vDato, vClav);

 

...

 

 

Este sistema se aplica a un gran conjunto de operaciones de los módulos internos SRRCM (M en javascript) y de SRRCN (N en javascript), concretamente, a las lecturas secuenciales, a las lecturas por clave y a los accesos por clave (chain).

 

                                                                                                  _________

 

 

 

5 Funciones específicas que surgen por la aparición de lógicos. La función CRTLF

 

Las operaciones de actualización y borrado conllevan operaciones adicionales pues deben aplicarse al fichero solicitado y a los relacionados con el en caso de pertenecer a una base de datos, esto es, un fichero físico base y su conjunto de lógicos.

 

El prototipo de la nueva función que surge para crear lógicos en SRRCW es:

 

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

//

// 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

//               (IMPORTANTE: Formato 1..N para facilitar uso desde 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)

 

 

Y las sentencias principales asociadas a la creación de un fichero lógico son

 

. . .

 

// Obtiene el identificador del PF

 

lNIDwf = SRRCW_VERDBR(cPF, cPFb);     // Cuando ya hay dbr asociada

if (!lNIDwf) lNIDwf = SRRCW_NID(cPF); // Cuando es un PF único

 

. . .

 

 

// Genera el identificador del LF a crear

 

lNIDwl = SRRCW_NEW(cLF, iKLEN, lDimD);

 

 

// Genera la vía de acceso asociada, duplicando los datos del físico base al nuevo

// lógico relacionado, en una implementación de tipo replicativo, aplicando la

// definición de posición de comienzo de la clave lógica para poder grabar

// correctamente la clave de acceso del nuevo fichero en la zona marcada

 

for (l=1;;++l)

{

 SRRCM_READ(lNIDwf, l, cDatoW);

 SRRCM_WRITE(lNIDwl, cDatoW + iKPOS - 1, cDatoW);

}

 

 

// Graba enlace físico-lógico

 

memcpy(cDatoW, cPFb, 33);

memcpy(cDatoW+33, cLF, 33);

lresul = SRRCM_WRITE(lNIDpf, cDatoW, cLF);

 

 

// Graba enlace lógico-físico-posición claves

 

memcpy(cDatoW, cPFb, 33);

memcpy(cDatoW+33, &iKPOS, sizeof(int));

lresul = SRRCM_WRITE(lNIDlf, cLF, cDatoW);

 

 

// Devuelve el identificador del lógico construido

 

return lNIDwl;

 

. . .

                                                                                                  _________

 

 

y la conversión a javascript correspondiente sería

 

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

//

// Función  W_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

//

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

function W_CRTLF(cLF, cPF, iKPOS, iKLEN)

{

 

 Y las sentencias principales asociadas son

 

. . .

 

 // obtiene nid del PF indicado

 

 lNIDwf = W_VERDBR(cPFw, cPFb);     // Cuando ya hay dbr asociada

 if (!lNIDwf) lNIDwf = W_NID(cPFw); // Cuando es un PF único

 

. . .

 

 

 // Genera nid del LF a crear

 

 lNIDwl = W_NEW(cLFw, iKLEN, WlDimD);

 

 

 // Genera la vía de acceso asociada, duplicando los datos del físico base al nuevo

 // fichero lógico relacionado

 

 for (l=1;;++l)

 {

  er = M_READ(lNIDwf, l, cDatoW);

 

  cDatW = cDatoW[0];

  cClaW = cDatW.substr(iKPOS - 1);

 

  lresul = M_WRITE(lNIDwl, cClaW, cDatW);

 }

 

 

 // Graba enlace físico-lógico

 

 cDatW = cPFw + cLFw;

 lresul = M_WRITE(lNIDpf, cDatW, cLFw);

 

 

 // Graba enlace lógico-físico

 

 cDatW = cPFw + (iKPOS + lKTE).toString();

 lresul = M_WRITE(lNIDlf, cLFw, cDatW);

 

 

 // Devuelve nid del lógico construido

 

 return lNIDwl;

 

. . .

 

                                                                                                  _________

 

 

 

En el CRTLF surgen entonces dos nuevos ficheros virtuales de uso interno de tipo M (SRRCM en la implementación original en C), “lNIDpf” que archiva los enlaces de físico-lógicos y “lNIDlf” que guarda los enlaces de lógicos-físicos y la posición de las claves lógicas

 

 

El esquema de funcionamiento de estos ficheros resulta como sigue:

 

Además de los ficheros creados por el usuario tendremos tres ficheros más de uso interno dedicados al archivo de relaciones, cuyos identificadores se guardan en las variables globales del programa SRRCW definidas a continuación

 

static long lNIDf;  // Nid asociado a enlace de nombres y nid’s

static long lNIDpf; // Nid asociado a enlace de físicos y lógicos

static long lNIDlf; // Nid asociado a enlace de lógicos y físicos

 

 

-Por tanto, de un lado tendremos el fichero de relaciones entre nombres e

 identificadores “lNIDf”, cuyos datos se registrarían como en la siguiente tabla

 tipo, que vimos antes al presentar la función NEW y que volvemos a presentar

 ahora en el marco ampliado de relaciones:

 

 

 

 

 

Fichero de relaciones que se graba

Nombre dado

Identificador generado

    Clave

Datos

(Relaciones01)

1 [lNIDf]

      -

-

(Relaciones02)

2 [lNIDpf]

      -

-

(Relaciones03)

3 [lNIDlf]

      -

-

EJEMPLO”

2

      EJEMPLO

2

EJEMPLO01”

3

EJEMPLO01

3

EJEMPLO02”

4

EJEMPLO02

4

EJEMPLO03”

5

EJEMPLO03

5

EJEMPLO04”

6

EJEMPLO04

6

EJEMPLO05”

7

EJEMPLO05

7

. . .

 

   . . .

 

 

 

 

Este primer enlace se emplea para acceder a la aplicación núcleo M (SRRCM en la implementación original en C)

 

                                                                                                  _________

 

 

 

-Por otro lado tendremos el fichero de enlace de físico-lógicos “lNIDpf”

 

 

Nº Relativo registro

Clave

Dato

1

EJEMPLO EJEMPLO01

EJEMPLO01

2

EJEMPLO EJEMPLO02

EJEMPLO02

3

EJEMPLO EJEMPLO03

EJEMPLO03

4

EJEMPLO EJEMPLO04

EJEMPLO04

5

EJEMPLO EJEMPLO05

EJEMPLO05

. . .

 

 

 

 

Este segundo fichero de enlaces se usa para duplicar operaciones al conjunto de la base de datos formada por EJEMPLO y sus lógicos EJEMPLO01, 02 ...

 

 

-Y además estará el fichero de enlace de lógicos-físicos-posición claves “lNIDlf”

 

 

Nº Relativo registro

Clave

Datos

1

EJEMPLO01

EJEMPLO 5 (Según iKPOS recibido)

2

EJEMPLO02

EJEMPLO 9

3

EJEMPLO03

EJEMPLO 20

4

EJEMPLO04

EJEMPLO 24

5

EJEMPLO05

EJEMPLO 25

. . .

 

 

 

Este tercer tipo de enlace complementa al anterior en las operaciones de detalle de la replicación.

 

 

Podemos apreciar la conjunción de estas relaciones en la función DELETE que se expone a continuación

 

                                                                                                  _________

 

6 La función DELETE

 

A partir de los ficheros de relaciones entre físicos y lógicos, se pueden codificar las operaciones de actualización para una base de datos constituida por un fichero físico y sus lógicos relacionados.

 

Veámoslo en detalle con DELETE, presentando un extracto de las funciones originales en C y viendo luego la conversión a javascript.

 

Empezamos con el prototipo original de la función en C:

 

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

// 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

//

// Retorno: Posición índice del registro suprimido

//          0 Error de proceso (Clave inexistente ...)

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

//

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

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

 

 

Cuya codificación se extracta a continuación

 

. . .

 

// Recupera el identificador correspondiente al fichero solicitado

 

lNIDw = SRRCW_NID(cFILE);

 

 

// Proceso:

//

// Recupera datos, elimina registro base y extiende la operación con DUPLIDELETE a toda la dbr asociada

 

 

// Recupera los datos del registro solicitado para borrar

 

lResul = SRRCM_CHAIN(lNIDw, vClav, cDatoW);

 

 

// Borra el registro del fichero indicado y lo aplica a la dbr asociada

 

lResul = SRRCM_DELETE(lNIDw, vClav);

if (lResul) er = SRRCW_DUPLIDELETE(cFILEw, vClav, cDatoW);

 

return lResul;

. . .

                                                                                                  _________

 

 

 

La replicación de la operación en DUPLIDELETE al conjunto de ficheros relacionados se codifica en la función interna auxiliar de prototipo:

 

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

// Función SRRCW_DUPLIDELETE

//

// Descripción Duplica un DELETE a la dbr asociada

//

// Parámetros

//

// (entrada) cFILE: Nombre de fichero solicitado

//           vClav: Clave del ítem

//          cDatDB: Datos que se suprimen, que incluyen por construcción todas las

//                  claves de la dbr

//

// Retorno 0 Proceso satisfactorio

//        >0 Error de proceso

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

short int SRRCW_DUPLIDELETE(const char *cFILE, const void *vClav, const char *cDatDB)

 

 

Donde en esencia se aplicará la operación de borrado al registro correspondiente del fichero físico base y a continuación al resto de los ficheros relacionados, eludiendo el fichero de partida que ya se trató en la rutina de llamada.

 

Sigue un extracto del código

 

. . .

 

// Evalúa si cFILE es un fichero con dbr asociada

 

lNIDw = SRRCW_VERDBR(cFILE, cPFw); // Además extrae el nombre del físico base asociado

if (!lNIDw) return NO_ERRO;

 

 

// Duplica operación al fichero físico base (eludiendo el propio fichero ya tratado)

 

iComp = memcmp(cPFw, cFILE, 33*sizeof(char));

if (iComp) lresul = SRRCM_DELETE(lNIDw, cDatDB);

 

 

// Ciclo de duplicación de la operación solicitada a lógicos dependientes

 

lresul = SRRCN_SETLL(lNIDpf,cPFw,33); //Sitúa para leer el relactor de físicos-lógicos

 

for(;;)

{

 lresul = SRRCN_READE(lNIDpf, cPFw, 33, cDatoW, cClavW); // Lee la relación

 if (!lresul) break;

 

 

 // Extrae el siguiente nombre de lógico y su identificación (Tipo SRRCM)

 

 memcpy(cLFw, cDatoW, 33*sizeof(char));

 lNIDw = SRRCW_NID(cLFw);

 

 

 // Elude el propio fichero ya tratado

 

 iComp = memcmp(cFILE, cLFw, 33*sizeof(char));

 if (!iComp) continue;

 

 

 // Extrae la posición de clave del lógico en los datos del físico

 

 lresul = SRRCM_CHAIN(lNIDlf, cLFw, cDatoW);

 memcpy(&iKPOS, cDatoW+33, sizeof(int));

 

 

 // Duplica la operación

 

 lresul = SRRCM_DELETE(lNIDw, cDatDB + iKPOS - 1);

}

 

. . .

 

 

                                                                                                  _________

 

DUPLIDELETE, como el resto de mecanismos replicadores, utiliza una función auxiliar para determinar si un fichero está asociado a una base de datos, VERDBR, de prototipo

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

// Función SRRCW_VERDBR

//

// Descripción Evalúa si un nombre de fichero tiene dbr asociada

//

// Parámetros

//

// (entrada) cFILE: Nombre de fichero solicitado

// (salida)   cPF : Nombre del PF base asociado

//

// Retorno 0 No pertenece

//        >0 Nid del PF asociado

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

long SRRCW_VERDBR(const char *cFILE, char *cPF)

 

 

Rutina que va examinando los ficheros de relaciones.

 

Primero examina el fichero que relaciona los físicos y sus lógicos, y a continuación recorre la relación recíproca de lógicos-físicos.

 

Exponemos su código principal a continuación:

 

. . .

 

// Evalúa si cFILE es un físico con dbr asociada, examinando el fichero de

// relaciones entre físicos y lógicos

 

lresul = SRRCN_SETLL(lNIDpf, cFILE, 33);

lresul = SRRCN_READE(lNIDpf, cFILE, 33, cDatoW, cClavW);

if (lresul)

{

 memcpy(cPF, cClavW, 33*sizeof(char));

 lNIDw = SRRCW_NID(cPF);

 return lNIDw;

}

 

 

// Evalúa si cFILE es un lógico de una cierta dbr, examinando el fichero de

// relaciones entre lógicos y físicos

 

lresul = SRRCM_CHAIN(lNIDlf, cFILE, cPF);

if (!lresul) return lresul;

 

lNIDw = SRRCW_NID(cPF);

return lNIDw;

 

. . .

                                                                                                  _________

 

 

Veamos ahora el código convertido a javascript:

 

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

// Funciónn  W_DELETE

//

// Descripciónn  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 

//

// Retorno

//            0  Error de proceso

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

//

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

function W_DELETE(cFILE, vClav, lLong)

{

 . . .

 

 

 // Recupera estadísticos

 

 er = W_INF(cFILE, WiDimC, WlDimD, WlNITEM, WlBAJAS);

 

 

 

 // Proceso para longitud de clave completa   

 

 if (WiDimC <= lLong) return W_DELETEr(cFILE, vClav);     

                                                  

                                                  

 // Proceso para longitud de clave parcial    

                                                  

 lResu = W_SETLL(cFILE, vClav, lLong);

 if (lResu <= 0) return 0;

                                                  

                                                                 

 // Lee ítem para obtener claves de borrado                 

                                                                

 lResu = W_READE(cFILE, vClav, lLong, cDatoW, cClavW);

 if (lResu <= 0) return 0;

                                                                 

                                                                

 // Elimina item solicitado                                 

                                                                

 return W_DELETEr(cFILE, cClavW);                        

}

                                                                                                  _________

 

 

 

// Proceso base de eliminación de un registro por su clave completa (Formato compacto)

 

function W_DELETEr(cFILE, vClav)

{

. . .

 

 

 // NID del file solicitado

 

 lNIDw = W_NID(cFILEw);

 

 

 

 // Proceso

 

 

 // Recupera datos para extender la operación en duplidelete a toda la dbr asociada

 

 lResul = M_CHAIN(lNIDw, vClav, cDatoW);

 

 

 // Borra el registro solicitado para el fichero indicado y lo aplica a la dbr asociada

 

 lResul = M_DELETE(lNIDw, vClav);

 if (lResul) er = W_DUPLIDELETE(cFILEw, vClav, cDatoW[0]);

 

 return lResul;

}

                                                                                                  _________

 

 

 

El código de las funciones auxiliares se convierte de forma similar. Como ejemplo veamos un extracto de DUPLIDELETE:

 

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

// Función  W_DUPLIDELETE

//

// Descripción  Duplica un DELETE a la dbr asociada

//

// Parámetros 

//

// (entrada)   cFILE: Nombre de fichero solicitado

//             vClav: Clave del ítem

//            cDatDB: Datos que se suprimen, que incluyen por construcción todas las

//                    claves de la dbr

//

// Retorno     0 Proceso satisfactorio

//            >0 Error de proceso  

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

function W_DUPLIDELETE(cFILE, vClav, cDatDB)

{

 . . .

 

 // Duplica operación al fichero físico base (eludiendo el propio fichero)

 

 if (cPFw[0] != cFILE) lresul = M_DELETE(lNIDw, cDatDB);

 

 

 // Ciclo de duplicación de la operación solicitada a lógicos dependientes

 

 lresul = N_SETLL(lNIDpf, cPFw[0], lStandarName);

 for(;;)

 {

  lresul = N_READE(lNIDpf, cPFw[0], lStandarName, cDatoW, cClavW);

  if (!lresul) break;

 

 

  // nombre del lógico

 

  cLFw = cDatoW[0];

 

 

  // Elude el propio fichero

 

  if (cFILE == cLFw) continue;

 

 

  // Posición de clave del lógico en datos del físico

 

  lresul = M_CHAIN(lNIDlf, cLFw, cDatoW);

  iKPOS = parseInt(cDatoW[0].substr(lStandarName)) - lKTE;

 

 

  // Duplica la operación

 

  lNIDw  = W_NID(cLFw);

  lresul = M_DELETE(lNIDw, cDatDB.substr(iKPOS - 1));

 }

 

 return 0;

}

 

                                                                                                  _________

 

 

 

Con los mecanismos vistos en DELETE se cubre el repertorio de operaciones individuales, pues el funcionamiento sigue la misma línea para las demás. Pasamos entonces a examinar las operaciones globales.

 

 

                                                                                                  _________

 

 

7 Las operaciones globales CPY & DUP

 

Se exponen a continuación las operaciones específicas de carácter global añadidas en SRRCW: La copia de ficheros y la duplicación de bases de datos.

 

De este grupo de funciones globales no se han convertido ni el salvado ni la restauración de datos desde fichero real de respaldo en disco porque su correspondencia en javascript no procede.

Se puede hacer una versión de respaldo a cookie replicando el código de SAVF y RSTF originales al igual que hemos hecho con el resto de métodos, pero la solución resultante estaría sometida a grandes restricciones de tamaño y no resultaría satisfactoria.

 

 

El prototipo de la función de duplicado de una base de datos, que replica un fichero y sus lógicos en otra base de datos en C es

 

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

//

// Función: SRRCW_DUP

//

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

//

// Parámetros:

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

//           cDES: Nombre del fichero (“físico” principal) destino

//

// Retorno: Identificador principal de la nueva base de datos

//         0: Error de proceso

//        >0: NID de cDES

//

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

 

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

 

 

La codificación central de la función de duplicación es

 

...

 

 

// Recupera diseño origen

 

er = SRRCM_INF(lNIDw, &iDimC, &lDimD, &lNÍTEM, &lBAJAS, &lNIDD);

 

 

// Crea el nuevo fichero

 

lNID_DES = SRRCW_NEW(cDESw, iDimC, lDimD);

 

 

// Copia datos desde el fichero origen

 

lNCPY = SRRCW_CP(cORG, cDES, 0);

 

 

// Extiende la duplicación a los lógicos dependientes

//

// Manteniendo la relación NOMBREORIGEN como NOMBREDESTINO

//                         NOMBREORIGEN01    NOMBREDESTINO01

//                         NOMBREORIGEN02    NOMBREDESTINO02

//                         NOMBREORIGEN03    NOMBREDESTINO03

// . . .

 

er = SRRCW_DUPLIDUP(cORGw, cDESw);

 

...

                                                                                                  _________

 

 

 

La codificación de la copia es similar, ahora veremos la transcripción a javascript

 

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

//

// Función: W_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

//

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

function W_DUP(cORG, cDES)

{

 . . .

 

 // Normaliza nombres

 

 cDESw = W_NAME(cDES);

 cORGw = W_NAME(cORG);

 

 

 

 // Recupera NID origen

 

 lNIDw = W_NID(cORGw);

 

 

 

 // Recupera estadísticas

 

 er = M_INF(lNIDw, WiDimC, WlDimD, WlNITEM, WlBAJAS);

 

 

 

 // Crea el nuevo fichero

 

 lNID_DES = W_NEW(cDESw, WiDimC[0], WlDimD[0]);

 

 

 

 // Copia datos desde el fichero origen

 

 lNCPY = W_CP(cORG, cDES, 0);

 

 

 

 // Extiende la duplicación a los lógicos dependientes

 

 er = W_DUPLIDUP(cORGw, cDESw);

 

 return lNID_DES;

 

 . . .

 

                                                                                                  _________

 

 

 

 El código de ambas versiones invoca a una serie de funciones auxiliares que se transcriben siguiendo el mismo proceso. Se invita a consultar el código completo de w_ficherosvirtuales_com. También puede consultarse el capítulo homólogo del blog original citado anteriormente.

 

                                                                                                  _________