Novedades (v1.0.0-rc29 → v1.8.33)
Esta página resume los cambios más destacados desde la versión v1.0.0-rc29. Para el historial completo de commits, consulta el CHANGELOG.
Destacados v1.8.33
Fix: Resolución de path en AdsCreateIndex legacy
El wrapper legacy AdsCreateIndex (usado por Harbour’s INDEX ON ... TO)
no resolvía paths de índice igual que AdsCreateIndex61:
- Bag vacío → no creaba CDX structural
- Paths relativos → no resolvía contra directorio de tabla
- Sin extensión → caía a creación NTX
Esto causaba que INDEX ON field TO filename fallara. El fix replica la
lógica de resolución de AdsCreateIndex61.
Tests de resolución de path para creación de índices
8 nuevos test cases cubriendo various formas de path: sin extensión, con extensión, paths absolutos, bag vacío, subdirectorio, backslash, wrapper legacy, y round-trip create+reopen.
Destacados v1.8.32
Cobertura comprehensiva de tests de bloqueo
Nueva suite de tests (abi_lock_comprehensive_test.cpp) con 23 test cases
que cubren superficies de API de bloqueo previamente no testeadas.
Comportamientos documentados:
| API | Comportamiento |
|---|---|
AdsGetNumLocks |
Cuenta solo locks de registro — locks de tabla no incluidos |
AdsTestRecLocks |
No-op diagnóstico: siempre retorna 0 sin importar el estado |
AdsIsTableLocked |
Refleja solo AdsLockTable — exclusive open no se reporta |
| Lock re-entrant | 2x AdsLockRecord en mismo recno requiere 2x AdsUnlockRecord |
Tests de contención de bloqueo REMOTE (escenarios de Pritpal Bedi)
6 nuevos tests que reproducen escenarios de bloqueo multi-instancia por TCP:
- Contención de lock de registro falla limpiamente (no se cuelga)
- Write sin lock retorna error 5035 (guard GoHot)
- Contención de FLock se resuelve dentro de la ventana de retry
- FLock permite writes sin lock de registro explícito
- Exclusive open permite writes (modo remoto)
- Append auto-lock funciona por wire
Destacados v1.8.21
El servidor muestra la versión al arrancar
openads_serverd incluye la versión del build en el banner de arranque
y en el registro de errores (misma cadena que --version).
Destacados v1.8.20
Studio HTTP en paquetes Windows + props DD para rddads
Los builds de release de Windows incluyen openads_serverd con
OPENADS_WITH_HTTP=ON: --http-port 6263 habilita Studio en
http://localhost:6263.
ace.h define las propiedades DD de SAP 121–130, incluida
ADS_DD_DISABLE_DLL_CACHING (125) que necesita Harbour rddads.
Destacados v1.8.19
REMOTO — scope + SET DELETED ON: sin filas fantasma en xBrowse
OrdKeyCount contaba claves de registros borrados dentro del scope
mientras la navegación los saltaba. xBrowse de FiveWin mostraba filas
en blanco / saltos y a veces no cerraba. El contador de claves ahora
coincide con el walk vivo. Actualizar DLL y openads_serverd.
Destacados v1.8.18
API de sistema de archivos en el servidor (oads_* / Ads*)
Los clientes pueden crear, borrar, renombrar y listar ficheros y directorios bajo el directorio de datos del servidor sin unidad mapeada (estilo LetoDB, nombres OpenADS).
| Capacidad | Funciones ACE |
|---|---|
| Existe / borrar / renombrar | AdsCheckExistence, AdsDeleteFile, AdsRenameFile |
| Tamaño / hora / fecha | AdsGetFileSize, AdsGetFileTime, AdsGetFileDate |
| Listado / carpetas | AdsDirectory, AdsDirExist, AdsDirMake, AdsDirRemove |
| E/S de bajo nivel | AdsFOpen · AdsFCreate · AdsFClose · AdsFRead · AdsFWrite · AdsFSeek |
Seguridad: en remoto hace falta EnableFileFunc=1 en openads.ini
o --enable-file-func (por defecto desactivado). Las rutas quedan
enjauladas bajo --data.
Guía (EN): Server filesystem. Documentación
por función (EN): API Reference y páginas bajo
/en/functions/ads-…. Actualizar cliente y openads_serverd.
Binarios Windows x64/x86 en el release v1.8.18.
Destacados v1.8.17
REMOTO — DbCreate / AdsCreateTable ya no escribe junto a la app
Con AdsConnect60(tcp://…), el create escribía en el cwd del
cliente y el open remoto fallaba con ADSCDX/5103. Create/drop
van por el cable al directorio de datos del servidor. Actualizar
DLL y openads_serverd.
Destacados v1.8.14
SQL — el cursor del resultado ya no empieza en una fila vacía fantasma
AdsExecuteSQLDirect / AdsExecuteSQL dejaban el cursor del
resultado antes de la primera fila, donde SAP ADS lo posiciona
sobre la primera fila — leer el registro actual justo después de
ejecutar devolvía una fila vacía fantasma en cada consulta. El
resultado ahora aterriza en la fila 1, igual que SAP, para tablas del
motor, resultados system.*/agregados, cursores de backends SQL y
clientes remotos por igual. Los llamadores que ya hacen AdsGotoTop
primero no se ven afectados.
REMOTO — read-ahead hacia atrás (PgUp)
El read-ahead era solo hacia adelante: un browse con Skip(-1)
pagaba un viaje de red por fila. Los recorridos inversos ahora
también precargan — un recorrido inverso de 300 filas pasó de 299
peticiones de red a 7 — y un nuevo bit de capacidad mantiene
correctas las combinaciones de cliente/servidor antiguos y nuevos en
ambas direcciones.
La versión real del servidor ahora es visible desde el cliente
Los repetidos informes de “la corrección no funcionó” seguían
resolviéndose en un openads_serverd antiguo aún en ejecución (un
servicio de Windows activo mantiene su exe abierto, así que copiar
una actualización encima puede fallar en silencio) — y no había forma
de demostrarlo desde el cliente: el handshake del protocolo y
AdsMgGetInstallInfo respondían cadenas fijas. Ahora el handshake
lleva la versión real de compilación (openads/1.8.14), y
AdsMgGetInstallInfo sobre un handle de gestión remoto informa
de la versión del servidor — contra cualquier servidor publicado
(las versiones antiguas se identifican como 0.3.2). Desde Harbour:
AdsMgConnect("host:port"), AdsMgGetInstallInfo()[3],
AdsMgDisconnect().
REMOTO — CloseTable dejaba los ficheros de la tabla abiertos en el servidor
Cerrar una tabla remota liberaba la vista del cliente, pero el handle
“sombra” del lado servidor (usado para navegación ordenada, scopes y
bloqueos) seguía abierto hasta desconectar la sesión — así que borrar,
renombrar o reabrir en exclusiva el .dbf/.cdx/.fpt recién
cerrado fallaba con “fichero en uso”, y los bucles de reintento de la
aplicación lo convertían en segundos de espera o un aparente cuelgue
al cerrar todos los ficheros. CloseTable ahora cierra el handle
sombra junto con la tabla.
Actualiza openads_serverd para la corrección de CloseTable;
actualiza también openace64.dll para ver la versión del servidor
desde el cliente. Nuevo ejemplo:
examples/fivewin/xbpaint_delscope.prg (registra la versión del
servidor y reproduce la forma exacta de repintado de xBrowse —
lecturas de página, AdsGetRelKeyPos/AdsSetRelKeyPos, arrastres de
la barra de scroll — sobre una tabla remota con scope y
SET DELETED ON).
Destacados v1.8.13
REMOTO — browses con orden/scope: correcciones + read-ahead
Cierra el trabajo remoto de SET DELETED: cambiar AdsShowDeleted
ahora invalida el bloque de lectura adelantada del cliente (los
registros borrados ya no persisten a mitad de recorrido), las
relaciones leen la clave del padre de la fila actual del cliente en
vez del cursor rezagado del servidor, y Seek/SetIndexOrder/
GetRecord ya no sirven filas precargadas obsoletas. El read-ahead
funciona ahora también en browses con orden (un recorrido ordenado
de 299 filas pasó de 598 viajes de red a 7), AdsCacheRecords se
respeta, y GotoTop/Seek devuelven la fila alcanzada, así que la
primera lectura tras reposicionar no cuesta un viaje extra.
Actualiza ambos binarios: openads_serverd y openace64.dll —
varias de estas correcciones son del lado cliente. Nuevo ejemplo:
examples/fivewin/xbrowse_delscope.prg (xBrowse FWH, remoto,
SET DELETED ON + scope de índice, borrados dentro del scope).
Destacados v1.8.12
ENGINE — Skip multi-registro sobre filas borradas
Continuación de v1.8.10/v1.8.11: con el filtro de borrados activo, un
browse remoto en orden natural podía mostrar un duplicado de la fila
anterior donde antes aparecía un registro borrado, o terminar el
recorrido unas filas antes. Table::skip calculaba los saltos
multi-registro con aritmética física de recno; ahora cuenta filas
visibles, igual que la ruta con índice y la semántica SKIP n de
Clipper. También corrige dbSkip(n > 1) LOCAL sobre filas
borradas/filtradas.
Requiere openads_serverd actualizado (y openace64.dll para modo
LOCAL). Pruebas de regresión: tres casos M12.33 en
abi_remote_index_nav_test.cpp.
Destacados v1.8.11
REMOTO — SET DELETED ON antes de conectar
Continuación de v1.8.10: el indicador ahora también llega al servidor
cuando SET DELETED ON se ejecuta antes de AdsConnect60 — el
orden que usa cualquier aplicación rddads / FiveWin. El cliente
sincroniza el estado justo después de conectar, y el servidor lo
reaplica a la conexión ABI (creación diferida) usada para la
navegación ordenada/con ámbito.
Requiere openace64.dll y openads_serverd actualizados. Pruebas:
remote scoped walk honours SET DELETED ON issued before connect
(+ … before first ordered op); sonda de red
tools/remote_deleted_probe.cpp.
Destacados v1.8.10
REMOTO — SET DELETED ON en recorridos con ámbito
AdsShowDeleted(0) (SET DELETED ON) ahora se propaga al servidor por
wire (ShowDeleted 0xDA/0xDB). La navegación indexada con ámbito
(OrdScope / AdsSetScope + GotoTop/Skip) ya no devuelve filas
marcadas como eliminadas en alias remotos.
Requiere openace64.dll y openads_serverd actualizados. Prueba:
remote AdsSetScope with SET DELETED ON skips deleted rows.
Destacados v1.8.1
ABI — relleno de claves OrdScope en campos carácter
Harbour envía el ámbito con longitud recortada, pero las claves CDX van
rellenadas con espacios. setScopeTop / setScopeBottom en un campo de
orden de trabajo podía dejar GotoTop en EOF en local y remoto.
AdsSetScope ahora rellena hasta key_length. Prueba: QA-D.
Destacados v1.8.0
CDX — colación OEM NTXPL852 / PL852
AdsSetCollation acepta NTXPL852 y PL852 para ordenar índices CDX
según CP-852 polaco. Ł (0x9D) queda entre L y M en build, seek, insert
y reindex.
CDX — REINDEX en bloque
Table::reindex() en tags CDX usa build_bulk() (misma ruta rápida que
CREATE INDEX).
Pruebas
19 pruebas unitarias nuevas (motor, driver CDX y ABI).
Destacados v1.7.0
REMOTO — AdsSetScope / OrdScope
Los límites superior/inferior de OrdScope se enviaban al servidor, pero
GotoTop/Skip ignoraban el ámbito. Corregido en session.cpp y
remote_index_nav.cpp. Requiere openace64.dll y openads_serverd
actualizados.
Docs — aviso de rollback CDX
Migrando desde ADS documenta que los CDX escritos por
OpenADS usan el header RCHB de Harbour y no son legibles por SAP ACE
(error 7017).
Destacados v1.6.5
REMOTO — OrdKeyCount() y AdsGetDate()
OrdKeyCount()devolvía 0 en alias remotos — rejillas xBrowse vacías. Nuevo opcode wireGetKeyCount.AdsGetDate()fallaba en camposADS_DATEremotos cuando rddads pasaba un handleRemoteIndex.
Destacados v1.6.4
REMOTO — Correcciones para FiveWin TDataBase / ADSRDD (fechas y escrituras sin lock)
- Campos Date:
FieldGet/AdsGetJuliansobre columnasADS_DATEya no crashea con ACCESS_VIOLATION en modo remoto. Resolución segura de ordinales + caché de fila + normalización aYYYYMMDDen el servidor. - FieldPut sin lock: Ya no da AV. Devuelve
AE_RECORD_NOT_LOCKED(5035) cuando se escribe sinRLockprevio. El idiom “escribir el mismo valor para probar el lock” ahora funciona y generaEG_UNLOCKEDesperado. - Todos los paths de Get/Set remoto ahora son seguros con ordinales como punteros pequeños; lecturas repetidas y post-open/EOF son estables.
AdsGetAllLocksya no crashea (5000) en handles remotos.- Mejor forwarding de locks y manejo de writes tras
AppendRecord.
Requiere openace64.dll y openads_serverd actualizados. Ver CHANGELOG
completo.
Destacados v1.6.3
REMOTO / FWH — xBrowse sobre tcp://
Correcciones para Harbour ADSCDX + FWH xBrowse / TDataBase con tags
CDX de producción (OrdSetFocus, p. ej. CUSTNAME):
- Scrollbar (
AdsKeyNo) — posición lógica en el orden (1..n), noRecNofísico;AdsGetRelKeyPos/AdsSetRelKeyPosen índice remoto. DbGototras pintar — el servidor sincroniza el cursor ABI del índice enGotoRecord; las filas dejan de cambiar en cadaRefresh.- Subir en el tope —
AdsAtBOFtrasSkip(-1)en la clave #1; evita repetir la primera fila.
Requiere openace64.dll actualizado y openads_serverd con el sync en
GotoRecord. Tests en abi_remote_index_nav_test.
Destacados v1.6.2
Nombres de tags CDX SAP y FieldGet en fila nueva
Nombres correctos en CDX compuesto (CUSTNAME); AdsGetField en blanco
en BOF/EOF para td_blankrow() de FWH.
Destacados v1.5.1
Seguridad y endurecimiento remoto
Path jail en Connect remoto, unlock anidado coherente en LockMgr,
verificación TLS por defecto, y escrituras remotas de memo/Unicode/fecha/raw.
Harbour smoke CI
Job Windows en GitHub Actions + scripts run_harbour_smoke.ps1 /
bootstrap_harbour_ci.ps1.
ABI remoto (Fase 2)
AdsSetRelation, AdsSetRecord / AdsGetRecord, AdsCustomizeAOF en
tcp://. AdsAggregate / AdsFetchWhere local en tablas DBF.
Plus — escritura navegacional SQLite y MSSQL
Backends SQLite y MS SQL Server nativo (TDS) con
AdsAppendRecord / AdsSetString / AdsWriteRecord /
AdsDeleteRecord — paridad con MariaDB, PostgreSQL, Firebird y ODBC.
Relleno de ADS_STRING en lectura MSSQL.
Motor
Fixtures ADT/ADI en el repositorio; cabecera VFP 0x32 (autoinc + nullable).
Nuevas Funcionalidades
Driver de Tablas con SQLite
Un driver alternativo de tablas respaldado por SQLite está
disponible detrás del flag de CMake OPENADS_WITH_SQLITE. Cuando
se habilita, el motor puede abrir y manipular tablas a través de
un backend SQLite, proporcionando una capa de almacenamiento
alternativa. Nuevos archivos fuente:
src/sql_backend/sqlite_backend.cppsrc/sql_backend/sqlite_connection.cppsrc/sql_backend/sqlite_table.hsrc/sql_backend/sqlite_index.h
Backends SQL — PostgreSQL / MariaDB / ODBC (OpenADS Plus)
OpenADS ahora puede abrir tablas en PostgreSQL, MariaDB /
MySQL y cualquier motor accesible por ODBC detrás de la ABI
ACE, elegido por la URI de conexión (postgresql:// /
mariadb:// / odbc://), igual que el backend SQLite. Desde la
aplicación la tabla se comporta como cualquier área de trabajo —
navegación, lectura de campos y SEEK por columna funcionan.
Estos cuatro backends SQL viven detrás de un único registro
enchufable de backend-ops: cada uno registra una struct
BackendTableOps (17 punteros a función que reflejan las ops de
tabla), de modo que las ~17 funciones ABI de navegación / campos
quedan agnósticas al backend en vez de multiplicar un bloque if
por backend. Añadir otro backend (p. ej. Firebird, o MSSQL /
Oracle vía ODBC) es una struct de ops más una línea de registro.
Las rutas DBF / ADT local nativas y la remota tcp:// quedan
intactas. Los identificadores se validan a ASCII seguro y los
valores de SEEK usan parámetros preparados (sin concatenar
strings). Ver docs/OPENADS_PLUS.md.
Parches de Validación ADT (F1–F7, R1–R3)
La validación de tablas ADT ahora incluye un conjunto completo
de parches estructurales (F1–F7) y verificaciones a nivel de
registro (R1–R3), reforzando las garantías de integridad para
archivos .adt producidos por SAP Advantage.
Creación, Lectura, Escritura y Búsqueda en Índice ADT/ADI Nativo
OpenADS ahora puede operar de extremo a extremo con archivos
nativos .adt / .adi / .adm:
- Crear —
AdsCreateTable(ADS_ADT)escribe una cabecera de tabla válida, descriptores de campo y un almacén de memo.admopcional. - Escribir —
AdsAppendRecord/AdsWriteRecordpersisten filas y payloads de memo. - Leer — Reabrir, obtener campos, conteo de registros, ida y vuelta de memo.
- Índice —
AdsCreateIndex61construye bolsas.adi(primer tag víaAdiIndex::create, tags adicionales víaadd_tag). - Buscar —
AdsSeeken claves ADI de carácter y numéricas. - AUTOINC — contador sembrado desde filas existentes al abrir; bytes 139–143 del descriptor permanecen en cero en disco.
- Layout de memo ADM — bloques de 8 bytes con un prefijo de metadatos de 1024 bytes.
Ruta de Escritura ADI
El driver de índices ADI ahora soporta operaciones de escritura
— insert, erase y flush — incluyendo la decodificación de
recno de hoja densa y búsqueda de claves de carácter. Esto
completa el ciclo de lectura-escritura para índices ADI.
Despacho de Triggers (BEFORE / INSTEAD_OF / AFTER)
Los triggers ahora se ejecutan con el despacho de temporización adecuado:
- BEFORE — se ejecuta antes de la sentencia DML.
- INSTEAD_OF — reemplaza la DML en vistas.
- AFTER — se ejecuta tras la ejecución exitosa.
Se soportan orden por prioridad, tabla __error para fallos,
procedimientos almacenados sp_DisableTriggers /
sp_EnableTriggers, y claves compuestas de triggers en
system.triggers.
Interfaz de Gestión DA-Web
El reemplazo del Data Architect basado en navegador (DA-Web) ha recibido un trabajo extenso:
- Edición en línea de celdas con seguimiento de cambios visuales.
- Gestión de índices — guardar y eliminar índices vía API.
- CRUD de Triggers — agregar, eliminar y editar triggers con validación en línea.
- Barra de filtros AOF (Rushmore) en el explorador de tablas.
- Resaltado de sintaxis SQL ADS con colores similares a HeidiSQL.
- Visor de código de procedimientos almacenados / funciones con parámetros y Save-to-DD.
- Explorador de tags de índice, etiquetas de tipos de campo y scripts SQL.
- Menú de conexión — Nuevo DD, Abrir DD, Tablas libres.
- Pestañas de Permisos Efectivos y Miembros en paneles de usuario/grupo.
- Desplegables de tags RI poblados desde archivos
.addbinarios.
openmonitor — TUI y Panel Web
Una nueva herramienta openmonitor proporciona tanto una interfaz
de terminal (TUI) como un panel web para monitorear y administrar
openads_serverd.
OpenADS Studio — Responsive (teléfono / tablet)
La consola web Studio ahora se adapta a pantallas pequeñas — se
puede usar desde un teléfono o tablet, no solo desde un navegador
de escritorio. Por debajo de ~768 px la lista de tablas se
convierte en un drawer deslizante (☰ en el header, fondo
atenuado, cierre automático al elegir); la barra de pestañas hace
scroll horizontal y los formularios / modales se reorganizan en una
columna con objetivos táctiles más grandes. Se corrige además un
bug antiguo del tema oscuro — las variables CSS --panel /
--panel-2 / --border eran auto-referenciales, por lo que
paneles y bordes se mostraban transparentes.
Rendimiento de escaneo remoto (prefetch secuencial)
Un escaneo hacia adelante sobre el wire tcp:// costaba más o menos
un round-trip TCP por registro (Skip + AtEOF + IsFound). Un
camino de prefetch secuencial (negociado con un flag de capacidad en
Connect) ahora adjunta un bloque de lookahead a los acks de
Skip hacia adelante; el cliente los sirve localmente y vuelve a
plegar el conteo consumido en el siguiente paso del wire, de modo
que el cursor del servidor nunca se desincroniza. AdsAtEOF /
AdsAtBOF se responden desde la fila actual cacheada y AdsIsFound
desde un flag Found() cacheado. Resultado: un escaneo de 50k
registros en loopback es ~3.9× más rápido (solo NAV) / ~3.3×
(lectura de 3 campos), con los round-trips de IsFound a cero. El
cambio es aditivo y retrocompatible — los clientes antiguos (sin
capacidad anunciada) mantienen el comportamiento del wire idéntico.
Extensión Nativa PHP (php_openads)
Una extensión nativa Zend PHP (php_openads.dll) está ahora
disponible para PHP 8.x, proporcionando CRUD completo del DD (35
nuevos métodos AdsDictionary), decodificación de campos
date/timestamp y caché de nombres de campo por sentencia.
Mejoras en la Importación de Diccionario de Datos SAP
import_ddahora copia archivos de memo.amy decodifica cuerpos de funciones encriptados.- Importación de membresía de grupos (DB:Admin, DB:Backup,
DB:Debug) desde archivos
.addbinarios. - Temporización de triggers capturada desde
system.triggers. grant_permissiony código de errorAE_SAP_PERMS_NEED_IMPORTpara migración de permisos.
Recuperación de Fallos WAL
La recuperación de fallos WAL (Write-Ahead Log) ahora maneja
registros APPEND, completando el modelo de recuperación
ARIES-lite.
Expansión del SQL del DD
CREATE DATABASE,GRANT/REVOKE.- Procedimientos almacenados
sp_*. - Tablas virtuales
system.*(system.iota,system.columns). AdsDDGet/SetFieldProperty, triggers, procedimientos almacenados, vistas y propiedades de índices.- Control de acceso por tabla con niveles de permiso de usuario/grupo.
Agregación Server-Side (Tier-3)
AdsAggregate ahora soporta COUNT, SUM, AVG, MIN y
MAX con push-down a backends SQL (SQLite, PostgreSQL, MariaDB,
ODBC). La spec de agregación se valida antes de ejecutar, y los
resultados se sirven a través de un result set basado en handles
(AdsAggregateCount / AdsAggregateValue /
AdsAggregateClose).
FetchWhere V2
AdsFetchWhere ahora sirve escaneos hacia adelante desde un
result set cacheado — sin round-trip por coincidencia. El cliente
recibe filas en lote y las recorre localmente, con recno por fila
opcional (flag WANT_RECNO). Los escaneos masivos de SET FILTER
sin AOF se enrutan a través de AdsFetchWhere con ganancias
significativas de rendimiento.
Driver ODBC (slice 1–3)
Un driver ODBC completo (openads_odbc.dll) está ahora disponible:
- Round-trip SELECT con cursores scrollables
(
SQLFetchScroll). - Acceso tipado a columnas —
SQLDescribeCol/SQLColAttribute/SQLGetDatadespachan a través del vtable de ops del backend. - Binding posicional de parámetros vía
SQLBindParameter. - Funciones de catálogo —
SQLPrimaryKeys/system.primarykeys. - Emulación de app-lock —
rLock()/fLock()vía SQL Serversp_getapplock, locks advisories de PostgreSQL, locks con nombre de MariaDB y tablaOPENADS$LOCKSde Firebird.
Ruta de Escritura Nativa (PostgreSQL / MariaDB / Firebird)
AdsAppendRecord / AdsSetField / AdsWriteRecord /
AdsDeleteRecord ahora funcionan de extremo a extremo en
backends PostgreSQL, MariaDB y Firebird — sin passthrough ODBC.
Expansión del Push-Down SQL
Las expresiones de SET FILTER y AOF ahora se empujan a SQLite
y PostgreSQL como cláusulas WHERE cuando el árbol de expresiones
está dentro del subconjunto optimisable (try_emit_sql_where). La
cobertura incluye $ (contiene), LEFT(), RIGHT(),
SUBSTR() y UPPER().
Documentación Completa de la API (Portugués)
Las 364 funciones ACE están ahora documentadas en portugués
(pt-BR) bajo docs/pt/funcoes/, cubriendo sintaxis, parámetros,
valores de retorno y ejemplos.
Corrección de Calling Convention x86 (32-bit)
ENTRYPOINT ahora es __stdcall (WINAPI) en Win32, coincidiendo
con la convención de llamada de rddads de Harbour. Esto corrige
la corrupción de stack cuando apps Harbour de 32-bit llaman a
funciones ACE a través del DLL. El archivo .def de x86 y la
librería de importación se actualizan para coincidir. (Reportado
por Jonsson / RusSoft Ltda.)
CI — Build Leg msvc-x86
Una nueva entrada de matrix msvc-x86 en
.github/workflows/ci.yml asegura que builds de 32-bit se
prueben en cada PR, atrapando breakages exclusivos de x86
(reducción dependiente de bitness, conflictos de firma SQLLEN*,
advertencias /WX) antes de que lleguen a main.
Correcciones de Errores
Motor
- Orden de tags CDX —
list_tags()ahora ordena por offset del tag-header (orden de creación) en lugar del orden alfabético de la hoja. CorrigeDBSETORDER(n)seleccionando el tag incorrecto en bolsas CDX escritas por SAP ADS. (Reportado por Jonsson / RusSoft Ltda.) - Tamaño de clave de índice de expresión CDX — las claves de
expresiones compuestas (p. ej.
UPPER(cName)) ahora se dimensionan desde el ancho fijo natural de la expresión, no desde la longitud del contenido del primer registro. El antiguo rtrim truncaba claves, causando filas fuera de orden tras reindex en tablas grandes. (Reportado por Jonsson / RusSoft Ltda.) - Caminado de hojas vacías CDX — los caminados hacia adelante
y hacia atrás del índice ahora saltan hojas vacías dejadas por
erase(). CorrigeADSCDX/5000en REINDEX / borrado masivo. (PR #63) - Bits de recno en hoja CDX —
compute_layoutdimensiona el campo de número de registro desdemax_rec, no solo la longitud de clave, para que las tags con claves anchas ya no truncuen recnos ≥ 4096. (PR #62) - Búsqueda parcial CDX —
seek_keycompara solo la longitud de la clave de búsqueda, para que búsquedas parciales comoSEEK "ART-00024800"coincidan con claves almacenadas"ART-00024800 desc ...". (PR #62) - FOR condicional en campos lógicos — el evaluador de
expresiones de índice ahora trata los campos lógicos como
numéricos (0/1) en lugar de cadenas truthy, para que
FOR ACTIVEfiltre correctamente registros.F.. (PR #121) - Corrupción por INDEX ON — previene que
INDEX ONcorrompa índices de la tabla fuente. (PR #118) - SKIP hacia atrás MSSQL — error por uno:
abs_n == posahora llega a la fila 0 en lugar de reportar BOF. (PR #65) - Getters tipados ABI para backends SQL —
AdsGetDouble/Long/LongLong/Stringdespachan a través del vtable de ops del backend, para que PostgreSQL devuelva valores reales. (PR #66) AdsGetIndexHandlepara backends SQL — resuelve por nombre para tablas PG para que la búsqueda por índice funcione extremo a extremo. (PR #66)- Formato de clave numérica NTX — los campos numéricos
indexados en un bolsillo NTX ahora almacenan claves en el formato
nativo DBFNTX (magnitud rellenada con ceros + negativos
complementados) en lugar de texto
STR()rellenado con espacios. La búsqueda nativadbSeek(<number>)de un lector xBase ahora coincide con la clave en disco. Los bolsillos de índice reabiertos conservan la codificación numérica. (PR #67) dbSeeknumérico — rddads envía tipo de claveADS_STRINGpara búsquedas numéricas; el motor ahora lo maneja correctamente.ALIAS->FIELDen búsqueda numérica — elimina el prefijoALIAS->para que los tags CDX con alias encuentren claves.- Reversión de transacciones — elimina físicamente los registros agregados al revertir en lugar de dejar filas fantasma.
- Fuga de estado LockMgr —
held_ahora se limpia al desbloquear para que el siguiente bloqueo tome un bloqueo real del SO. AdsGetRecordCount— ahora respetabFilterOption.AdsSetRelation— falla honestamente cuando es apropiado.seek_key—walk_to_lastahora honraSET DELETED ON.- Navegación de tabla vacía — maneja correctamente tablas con cero registros.
- Navegación de registros eliminados — estado correcto tras saltar filas eliminadas.
- Recuento de bloqueos LockMgr — los bloqueos repetidos sobre la misma clave ahora se cuentan por referencia; el bloqueo del SO se libera solo cuando el último poseedor desbloquea.
- Comprobación de límites de registros WAL —
TxLog::read_allvalida la longitud de cada campo UPDATE/APPEND antes de leer, evitando lecturas excesivas en archivos WAL truncados o corruptos.
ABI
- Lectura fuera de límites en formato de clave numérica — prevenida.
- Bits de opción intercambiados —
ADS_DESCENDING(0x02) yADS_COMPOUND(0x08) se decodificaban incorrectamente enAdsCreateIndex61. - Resolución de nombres de campo insensible a mayúsculas —
field_indexse cachea para mejor rendimiento. AE_NO_CURRENT_RECORD— devuelve 5068 en lugar de 5026.OrdListAdd— vuelve al nombre base cuando una ruta relativa prefija doble el directorio de la tabla.- Vínculo de helpers trig — vínculo C++ para helpers
trig_*para silenciar MSVC C4190. - Crash de
AdsGetFielden backends SQL — leer por ordinal de campo ya no falla. - AdsGetRecordCount en ORDER condicional — cuenta coincidencias FOR correctamente. (PR #100)
AdsSetAOFpara filtros no optimizables — ahora devuelveAE_INVALID_EXPRESSIONen lugar de éxito, para que rddads stock caiga en filtrado del lado del cliente. El comportamiento anterior deshabilitaba silenciosamenteSET FILTERpor completo. (Reportado por Jonsson / RusSoft Ltda.)
Driver ODBC
- Build x86 —
C4100(parámetro no usado) yC2733(conflicto de firmaSQLLEN*vsSQLPOINTER) corregidos para 32-bit MSVC/WX. (PR #119) - Conformidad DM/ADO — manejadores de descriptor,
SQLBindColy mapeo de tipoBITcorregidos. SQL_DRIVER_ODBC_VER/SQL_ODBC_VER— ahora se reportan enSQLGetInfo.
Seguridad DA-Web
- Sanitización de expresiones de filtro AOF.
- Corrección de contención de ruta de raíz de unidad.
- Barrido de seguridad de API en todos los endpoints PHP.
- Rutas de índice RI meta contenidas bajo el directorio DD.
- Límites de tamaño de frame wire para prevenir abuso.
Plataforma / Build
- macOS — advertencias de sign-conversion y unused-function corregidas.
- GCC — advertencias
-Werrorresueltas (shadow, implicit conversion, format-truncation, stringop-truncation). - MSVC — decoración
__stdcallde x86 y crash de_wfsopenen x64 corregidos. - Clang — guardia
-Wc2y-extensionspara Apple Clang anterior. - Colisión de fd 0 en POSIX — los manejadores de archivo
ahora se almacenan como
(fd + 1)para que un fd 0 real (devuelto poropen()cuando stdin está cerrado) no se confunda con el centinela “no abierto”. - Reintento
EINTRen POSIX —pread/pwritereintentan ante interrupción por señal en lugar de fallar la E/S. - mmap de longitud cero en POSIX —
map_readonlyrechaza mapeos de longitud cero en lugar de llamar ammapcon longitud 0.
CDX
- Bloqueo de cabecera compartido al abrir para que las inserciones concurrentes no fallen.
- CDX estructural nombrado por tabla, no por sesión de directorio.
- Refresco del conteo de registros obsoleto en la ruta de
lectura — el driver cachea el conteo de registros del DBF al
abrir; en un despliegue multiusuario un append de otro proceso
podía dejar la caché desfasada, de modo que un recorrido por
índice que alcanzaba una fila recién agregada (p. ej. en mitad de
REPLACE … FOR) fallaba con un error 5000 espurio.read_record_raw/write_record_rawahora releen el conteo en disco bajo un bloqueo de cabecera compartido antes de declarar un recno fuera de rango (solo ruta lenta — un escaneo normal hacia adelante no paga nada).
Remoto (Wire)
- Crash de use-after-free en consultas de tablas virtuales vía TCP eliminado.
Documentación
- CONTRIBUTING.md — nueva guía de contribución con flujo de PR, política de protocolo y reglas de clean-room.
- Wire Protocol DD API — referencia completa de la API del Diccionario de Datos (§9) agregada.
- DA-Web GUIDE.md — guía completa de usuario para la interfaz de navegador DA-Web.
- README — actualización completa del estado post-rc29 cubriendo ruta de escritura ADI, creación ADT, modo AES y alcance de DA-Web.
- Cookbook — nueva carpeta
cookbook/con ejemplos Harbour ejecutables y muy comentados (simple → avanzado). La pistaconsole/es xBase puro: crear / seek por índice / transacciones / mantenimiento DBF (ADSCDX), SQL víaAdsCreateSQLStatement+AdsExecuteSQLDirect, ADT nativo (ADSADT+.adi) y un cliente remototcp://. La pistaorm/corre el mismo CRUD vía un ORM Harbour compañero sobre back-ends SQLite / DBF / PostgreSQL / MariaDB / ODBC, rematada por un benchmark de todos los back-ends (orm/complete/) con checksum de contenido entre back-ends y titular seek-vs-scan. Un ejemplo CRUDxbrowsede FiveWin y guías de cadenas de conexión / tipos de campo / resolución de problemas lo completan. - Referencia API (PT) — las 364 funciones ACE documentadas en portugués con sintaxis, parámetros, valores de retorno y ejemplos.
Empaquetado
- Instalador Windows Inno Setup (
openads-setup.iss). - Paquetes CPack con
openace32.lib/openace64.libgarantizados en archivos Windows. - Release CI —
openace{32,64}.libse incluyen automáticamente en archivos de release.
Pruebas
- 874 pruebas unitarias pasando en x64 y x86 (361 300+ aserciones).
- Nuevos archivos de prueba:
abi_cdx_tag_order_test.cpp(orden de creación de tags CDX),abi_cdx_expr_index_scale_test.cpp(tamaño de clave de índice de expresión a escala),abi_multitag_order_nav_test.cpp(navegación multi-tag),abi_ntx_numeric_edge_test.cpp(casos límite numéricos NTX),cdx_empty_tree_test.cppy más. - CI x86 — build leg
msvc-x86atrapa breakages de 32-bit en cada PR. - Demo de Harbour en
examples/adt-native/(por glokcode).
Contribuidores
- Jonsson / RusSoft Ltda. — correcciones de orden de tags CDX,
tamaño de clave de índice de expresión, filtro no optimizable de
AdsSetAOFy calling convention x86. - Admnwk — driver ODBC, push-down SQL, agregación, FetchWhere V2, ruta de escritura nativa y mejoras de CI.