El archivo indexado de RustCOBOL no es compatible con Fujitsu en términos de estructura de archivo, pero implementa el 99 % de la especificación COBOL-85 utilizada por Fujitsu COBOL85, lo que facilita la conversión de datos de un formato a otro prácticamente sin impactos en el código.
RustCOBOL y TODOS sus componentes son OPEN-SOURCE y GRATUITOS. Nada de licencias pagas, aunque en el futuro podamos ofrecer soporte pago. Nuevamente: el compilador, el RAD y las herramientas son 100 % gratuitos. ¡100 %!
En este momento estamos intentando, tanto como sea posible, evitar dependencias externas. Todavía no tenemos, por ejemplo, soporte para videos H.264 por el simple hecho de que esto requiere componentes externos, aunque sean gratuitos. Queremos una implementación limpia, 100 % Rust.
El widget de acceso a base de datos soporta SQLite, PostgreSQL y MySQL a través de bibliotecas Rust.
Sobre el sistema de archivos indexados de RustCOBOL (ISAM)
1. Arquitectura
Un único trait
IndexedStore (
crates/cobolt-runtime/src/indexed.rs) define la interfaz que utiliza el intérprete. Hay dos backends detrás de un
Box<dyn IndexedStore>:
| Backend | STORAGE IS | Archivo | Característica[/TH][/TR]
|
| IndexedFile (memoria) | MEMORY | indexed.rs | todo en RAM; se guarda en CLOSE
|
| DiskIndexedFile (disco) | DISK (por defecto) | indexed_disk.rs | archivo paginado persistente, leído bajo demanda
|
Sin dependencias externas — motor ISAM propio.
“Sabor” de engine:
Código:
--indexed-engine {rust|rm-cobol85|fujitsu}
o:
Código:
COBOL_INDEXED_ENGINE
Actualmente,
rm y
fujitsu delegan al engine Rust.
Los verbos de archivo son despachados por la
ORGANIZATION del
SELECT.
2. Engine de memoria (indexed.rs)
Código:
records: BTreeMap<clave-primaria, registro> // KSDS ordenado
alt_index: Vec<BTreeMap<clave-alt, BTreeSet<RecordId>>>
locks: HashMap<clave, LockMode{Shared|Exclusive}>
journal: Vec<Journal{Insert|Update|Delete}> // undo para ROLLBACK
BTreeMap proporciona ordenación natural para
START,
READ NEXT y
READ PREVIOUS.
3. Engine de disco (indexed_disk.rs) — formato PRCIDXD1
Páginas fijas de 4 KiB, con free-list. Las páginas liberadas son reutilizadas. Los punteros y contadores son
u64.
B+tree por clave — primaria + alternativas: hojas/internas byte-packed, split en la inserción y hojas doblemente encadenadas para barrido ordenado.
Directorio de
RecordId:
RecordId estable → ubicación física. Un
REWRITE que mueve el registro actualiza solo el directorio.
Slotted data pages: varios registros por página + cadena de overflow para registros mayores que una página.
WITH COMPRESSION: RLE estilo PackBits (
compress.rs), rápido, y nunca crece más de 1 byte.
Undo log en ejecución — nuevo en v1.8.0: soporta
ROLLBACK real. Antes era no-op.
4. Transacciones COMMIT / ROLLBACK (v1.8.0)
Semántica — se aplican a todos los archivos
INDEXED abiertos:
| Verbo | Efecto[/TH][/TR]
|
| OPEN | inicia una transacción
|
| COMMIT | hace durable todo desde el último COMMIT/OPEN e inicia una nueva transacción
|
| ROLLBACK | deshace todo WRITE/REWRITE/DELETE desde el último COMMIT/OPEN
|
| CLOSE | persiste los cambios mediante commit implícito
|
Implementación: el engine acumula un undo log con operaciones inversas:
- Insert → delete
- Update → reescribe la imagen anterior
- Delete → regraba la imagen anterior
ROLLBACK reaplica los inversos en orden reverso, con guard
tx_replay para no registrar nuevamente en el log, y vuelve a persistir.
COMMIT descarta el log y ejecuta
sync_all.
COMMIT y
ROLLBACK son tokens reservados. No son absorbidos por un
DISPLAY anterior.
Atención: es rollback a nivel de programa, dentro de la ejecución. La recuperación post-crash mediante WAL durable sigue siendo trabajo futuro.
5. Recursos implementados
Claves:
RECORD KEY única + N
ALTERNATE RECORD KEY [WITH DUPLICATES].
Modos de acceso:
Código:
ACCESS MODE SEQUENTIAL
ACCESS MODE RANDOM
ACCESS MODE DYNAMIC
Verbos:
Código:
OPEN {INPUT|OUTPUT|I-O|EXTEND} [SHARING WITH …][WITH LOCK]
CLOSE
WRITE (INVALID KEY)
REWRITE
DELETE
READ (random / NEXT/PREVIOUS / KEY IS altkey / WITH [NO] LOCK)
START KEY IS {= > >= < <=}
UNLOCK
COMMIT
ROLLBACK
FILE STATUS de 2 dígitos:
Código:
00, 02, 10, 22, 23, 24, 35, 46, 47/48/49, 99, …
Bloqueo de registros, modelo KSDS, más journal/undo, persistencia, compresión opcional y selección de almacenamiento/engine.
6. Ejemplos de uso — ejecutados ahora
(1) CRUD con clave primaria + alternativa, DISK WITH COMPRESSION
Flujo:
Código:
OPEN OUTPUT/I-O
WRITE
READ random
INVALID KEY
REWRITE
START GREATER + READ NEXT
READ KEY IS (alternativa, duplicados)
DELETE
Salida:
Código:
RANDOM 0002: BRUNO
0099 INVALID KEY, ST=23
REWRITE ST=00
SEQ 0001 ANA
SEQ 0002 BRUNINHO ← REWRITE aplicado; orden por clave primaria
SEQ 0003 CARLOS
ALT SP #1: CARLOS ← lectura por clave alternativa CIDADE="SP"
ALT SP #2: BRUNINHO ← READ NEXT en el duplicado
DELETE 0001 ST=00
0001 apagado, ST=23
FIM
(2) Persistencia entre ejecuciones
Otro proceso solo lee el archivo
/tmp/clientes.idx de la ejecución anterior:
Código:
Reabierto (otra ejecución). Registros persistidos:
0002 BRUNINHO SP
0003 CARLOS SP ← 0001 ANA sigue apagado; REWRITE/DELETE sobrevivieron
(3) Transacción COMMIT/ROLLBACK
Graba
GAMMA, hace
COMMIT. Después graba
DELTA, altera
ALPHA, borra
BETA y hace
ROLLBACK:
Código:
OPEN I-O F
MOVE 0003 ... WRITE R-REC *> GAMMA
COMMIT
MOVE 0004 ... WRITE R-REC *> DELTA
MOVE 0001 ... READ F MOVE "ALPHAX" ... REWRITE R-REC
MOVE 0002 ... DELETE F
ROLLBACK
Salida idéntica en los engines de disco y memoria:
Código:
Después del ROLLBACK, barrido:
0001 ALPHA ← REWRITE deshecho
0002 BETA ← DELETE deshecho
0003 GAMMA ← COMMIT anterior sobrevive
← 0004 DELTA removido (WRITE deshecho)
7. Cobertura de pruebas — verde ahora
| Suite (Rust) | Resultado
|
| test_transactions (COMMIT/ROLLBACK — disco y memoria) | 2 passed
|
| test_indexed (engine ISAM) | 2 passed
|
| test_file_locking (OPEN SHARING/LOCK, READ WITH [NO] LOCK, UNLOCK, CANCEL) | 4 passed
|
| test_fileio_storage (6 variantes: baseline + memory/disk × compression) | 7 passed
|
El acceso SQL previsto es nativo o mediante ODBC? (Drivers nativos de Rust para SQLite, MySQL y PostgreSQL)
Citación del post de
Joseg
|
❞
Gracias, buen trabajo,
José
|
Por falta de créditos, no tendremos avances hasta el próximo miércoles.
Conviértete en sponsor para descargar el código, seguir de cerca el progreso y contribuir con las pruebas.
¡Saludos!