Archivo vivo. Se actualiza diariamente con lo que se está haciendo, probando y verificando. No es un changelog — es un "qué está pasando ahora".
Un usuario FWH (FiveWin) reportó que al usar openads_serverd en modo
REMOTE con la clase TDatabase de FWH:
-
FieldGet crashea después de USE — En LOCAL mode el record buffer siempre está poblado después del open. En REMOTE no, y
FieldGetintenta leer de un buffer NULL → crash. -
Production CDX no se auto-asocia —
OrdBagName()devuelve vacío después de abrir la tabla. En LOCAL funciona correctamente. -
RddSetDefault("ADSCDX") falla — El usuario sospecha que está accediendo al archivo equivocado o que la secuencia de inicialización remota no es la misma que la local.
Se revisó el flujo completo de AdsOpenTable90 en modo REMOTE:
FWH: USE table VIA "ADSCDX"
→ AdsConnect60(tcp://host:port/, ADS_REMOTE_SERVER)
→ AdsOpenTable90(hConn, name, alias, ADS_CDX, ...)
→ Wire: OpenTable opcode → Server abre la tabla
→ Server: STAT del .cdx → envía prod_bag_path en OpenTableAck
→ Client: recibe OpenTableResult{id, prod_bag_path}
→ Client: auto-calls AdsOpenIndex(bag_path)
→ Wire: OpenIndex → Server abre CDX localmente
→ Server: retorna tags + bag_path
→ Client: crea RemoteIndex con bag_path
→ Client: resetea active_index_id = 0 (orden natural)
| Pregunta del usuario | Respuesta |
|---|---|
| ¿FieldGet es válido inmediatamente después del open? | NO. Se necesita DbGoTop() primero. El buffer del cliente está vacío. Esto es un bug real en ace64.dll que necesita fix. |
| ¿FieldGet en memo field funciona en REMOTE? | No funciona si no hay buffer previo. Los offsets de crash (0x2, 0xB) indican buffer pointer NULL. |
| ¿Hay un ejemplo de REMOTE contra DBF/CDX existente? | No había. Se creó uno nuevo (ver abajo). |
| Archivo | Líneas | Qué hace |
|---|---|---|
src/network/session.cpp |
554-616 | Opcode::OpenTable handler — abre tabla, STAT del CDX, envía bag_path |
src/network/session.cpp |
1321-1375 | Opcode::OpenIndex handler — abre CDX vía ABI, retorna tags + bag_path |
src/abi/ace_exports.cpp |
5200-5260 | AdsOpenTable90 remote path — auto-opens production CDX after table open |
src/abi/ace_exports.cpp |
9911-9965 | AdsOpenIndex remote path — crea RemoteIndex con bag_path |
src/abi/ace_exports.cpp |
23551-23580 | AdsGetIndexFilename remote — retorna bag_path del RemoteIndex |
src/session/connection.cpp |
166-251 | Connection::open_table — abre tabla + adjunta memo, pero NO abre CDX automáticamente |
src/network/client.cpp |
1171-1243 | RemoteConnection::open_index — parsea OpenIndexAck con tags + bag_path |
tests/unit/abi_remote_prodcdx_test.cpp — 8 test cases que validan
exactamente el workflow FWH contra un servidor remoto con datos reales:
| Test | Qué valida | Issue FWH |
|---|---|---|
OrdBagName returns production CDX bag path after open |
AdsGetNumIndexes > 0, AdsGetIndexFilename retorna nombre del CDX | #2 |
AdsGetIndexName returns tag names for all orders |
Cada orden tiene tag name válido | #2 |
GoTop + FieldGet on first record after open |
AdsGotoTop → AdsGetField no crashea | #1 |
DbSetOrder by number changes cursor order |
Cambiar orden cambia el registro top | #3 |
DbSetOrder by tag name |
Funciona por nombre, walk de registros | #3 |
Ordered full-scan counts match record count |
Scan completo con orden = record count total | General |
Multiple tables open simultaneously |
customer.dbf + invoices.dbf abiertos a la vez | General |
FieldGet on multiple fields after Skip |
FieldGet por nombre en todos los campos tras Skip | #1 |
- Servidor: iMac
192.168.18.184, puerto16262, data_dir/tmp/openads_mac - Datos:
customer.dbf(100 records, CDX production),invoices.dbf(1000 records, CDX),invoicedetail.dbf(3000 records, CDX),items.dbf(20 records, CDX) - SSH:
Anto@192.168.18.184, password1234 - Ejecución:
$env:OPENADS_TEST_REMOTE = "tcp://192.168.18.184:16262/"; .\openads_unit_tests.exe -tc="REMOTE*"
El bug real es que después de OpenTable remoto, el cursor del engine
queda en posición indefinida. En LOCAL mode, el engine deja el cursor
poblado (aunque en BOF). En REMOTE, el cliente no tiene ningún buffer
hasta que pide una navegación.
Opciones de fix:
-
Servidor: ejecutar GotoTop implícito después de OpenTable — El OpenTableAck podría incluir el recno actual y los primeros bytes del registro. Esto arregla el crash pero cambia la semántica (ADS no hace GoTop implícito).
-
Servidor: el OpenTableAck incluye el record buffer completo — Más datos por round-trip pero el cliente tiene todo de inmediato.
-
Cliente: AdsOpenTable90 hace GotoTop implícito en REMOTE — El cliente envía GotoTop después de recibir el OpenTableAck. Esto es lo más cercano al comportamiento LOCAL.
| Suite | Resultado |
|---|---|
| Unit tests locales (960 tests) | ✅ 960/960 passed |
| REMOTE prodcdx tests (8 tests) | ✅ 8/8 passed |
| Total assertions | 394,513 passed, 0 failed |
-
AdsGetNumIndexesreturns 0 in REMOTE — El código consultabaget_num_indexes()al servidor, que retornaba 0 porque el engine handle no tenía el production index abierto. Fix: contarrt->index_handles.size()localmente (ace_exports.cpp:13110). -
FieldGet crashea después de OpenTable en REMOTE — El buffer del registro estaba vacío después del open. En LOCAL el cursor queda en BOF con buffer válido. Fix: GoTop implícito después del auto-open del production CDX en
AdsOpenTable90(ace_exports.cpp:5260). Un round-trip extra por tabla abierta, trivial comparado con el crash. -
FieldGet por ordinal con string "1" — Los tests usaban
(UNSIGNED8*)"1"(string literal) que en 64-bit tiene dirección alta (>0x10000), por lo que el detector de ordinal no lo reconoce. Fix del test: usar el idiom ACE correctoreinterpret_cast<UNSIGNED8*>(static_cast<std::uintptr_t>(1)). El código del DLL ya era correcto. -
AdsGetIndexName retorna tag vacío — El CDX de customer tiene un tag estructural cuyo nombre es todo padding (se trimea a vacío). Fix del test: aceptar nombre vacío como válido para tags CDX estructurales de dBASE.
-
Test AdsSetIndexOrderByHandle asumía 2+ tags — customer.cdx solo tiene 1 tag. Fix del test: trabajar con 1 tag, comparar solo cuando hay 2+.
- Implementar fix para el crash de FieldGet en REMOTE → Hecho: GoTop implícito después de AdsOpenTable90 en modo REMOTE
- Agregar test de memo fields en REMOTE (las tablas actuales no tienen .fpt)
- Agregar test con
RddSetDefault("ADSCDX")para reproducir el caso exacto del usuario - Verificar que el fix funciona con la app real del usuario FWH
- Investigar por qué customer.cdx tiene tag con nombre vacío (posiblemente creado por herramienta que no pone nombre al tag default)