Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
109f398
feat(tools): add openmonitor — TUI and web dashboard for openads_serverd
Jun 18, 2026
cc835b4
Merge branch 'feat/tools-openmonitor' — openmonitor lab tool
Jun 18, 2026
8c202f7
feat(openads-plus): postgresql read and seek behind ACE ABI
Admnwk Jun 20, 2026
49b84ac
test: postgresql ABI e2e read/seek against real libpq
Admnwk Jun 20, 2026
40cbb95
fix(build): static-link MinGW runtime on Windows
Admnwk Jun 20, 2026
7b97f0e
docs(scripts): winlibs PATH fix and MSVC x64 postgres build recipe
Admnwk Jun 20, 2026
49dee03
feat: SQL passthrough via AdsExecuteSQLDirect on the SQLite backend
Admnwk Jun 20, 2026
5a9a9e9
fix: address review feedback on the SQL passthrough
Admnwk Jun 20, 2026
12b8947
refactor(openads-plus): postgres navigates by primary key, not ctid
Admnwk Jun 20, 2026
acc9f63
chore(scripts): require OPENADS_TOOLCHAIN_ROOT explicitly
Admnwk Jun 20, 2026
bdab6eb
fix(openads-plus): address review on the postgres backend
Admnwk Jun 20, 2026
ecb73c6
fix(abi): AdsSetDouble honors remote tables (tcp:// navigational writes)
Admnwk Jun 21, 2026
973d6f3
fix(abi): AdsSetLogical honors remote tables (tcp:// navigational wri…
Admnwk Jun 21, 2026
edf5f08
docs(spec): pluggable backend-ops registry for ace_exports
Admnwk Jun 21, 2026
e815475
docs(plan): backend-ops registry implementation plan
Admnwk Jun 21, 2026
409ab2e
feat(session): HandleRegistry::kind_of for backend dispatch
Admnwk Jun 21, 2026
2e19455
feat(abi): backend-ops vtable + HandleKind-keyed registry
Admnwk Jun 21, 2026
eee03f2
feat(abi): lifted SQLite table ops + registry dispatcher (not yet wired)
Admnwk Jun 21, 2026
68c247b
refactor(abi): route SQLite close+nav ops through the registry
Admnwk Jun 21, 2026
eac8971
refactor(abi): route SQLite field accessors through the registry
Admnwk Jun 21, 2026
05e8b28
refactor(abi): route SQLite record/index ops through the registry
Admnwk Jun 21, 2026
3725847
test(abi): snapshot/restore global ops table in registry test
Admnwk Jun 21, 2026
868ef8d
feat(openads-plus): integrate PostgreSQL backend onto the backend-ops…
Admnwk Jun 21, 2026
eb4d738
feat(openads-plus): integrate MariaDB backend onto the backend-ops re…
Admnwk Jun 21, 2026
62a0857
feat(openads-plus): integrate generic ODBC backend onto the backend-o…
Admnwk Jun 21, 2026
01ec930
fix(openads-plus): scope each SQL backend's includes to its own macro…
Admnwk Jun 21, 2026
248d2a1
fix(cmake): expand PostgreSQL_INCLUDE_DIRS in the find_package fallback
Admnwk Jun 21, 2026
3142984
Merge upstream/main (6d9345b): x86 __stdcall .def + x64 _wfsopen fix
Admnwk Jun 21, 2026
7dc54c4
docs: drop local toolchain path from the registry plan note
Admnwk Jun 21, 2026
e4a3d86
fix(build): clear -Werror/-WX warnings breaking CI
Admnwk Jun 22, 2026
5873381
fix(tests): add missing STL headers for libc++/strict builds
Admnwk Jun 22, 2026
97decbd
Merge upstream/main into integration/openadsplus (resync)
Admnwk Jun 22, 2026
b53035b
fix(engine): honor SET DELETED in natural-order SKIP
Admnwk Jun 22, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 120 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,12 @@ option(OPENADS_WITH_HTTP "Enable embedded HTTP web console (Studio) in openads_s
# OpenADS Plus — optional SQLite-backed table driver (static amalgamation).
# On by default; set OFF for dev builds that skip the FetchContent download.
option(OPENADS_WITH_SQLITE "Enable the SQLite-backed table driver (vendors the SQLite amalgamation via FetchContent)" ON)
# Optional PostgreSQL table driver (libpq). OFF by default.
option(OPENADS_WITH_POSTGRESQL "Enable PostgreSQL-backed table driver (libpq)" OFF)
# Optional MariaDB/MySQL table driver (libmariadb). OFF by default.
option(OPENADS_WITH_MARIADB "Enable MariaDB-backed table driver (libmariadb)" OFF)
# Optional generic ODBC table driver (system ODBC driver manager). OFF by default.
option(OPENADS_WITH_ODBC "Enable ODBC-backed table driver (system ODBC driver manager)" OFF)

# Pull in mbedtls FIRST so our strict /WX -Werror flags don't bleed
# into the upstream sources (C4200 zero-sized arrays etc). Each
Expand Down Expand Up @@ -160,12 +166,126 @@ if(OPENADS_WITH_SQLITE)
message(STATUS "OpenADS: SQLite-backed table driver enabled")
endif()

if(OPENADS_WITH_POSTGRESQL)
set(_openads_pg_linked FALSE)
set(OPENADS_LIBPQ_INCLUDE "" CACHE PATH "Directory containing libpq-fe.h")
set(OPENADS_LIBPQ_LIBRARY "" CACHE FILEPATH "libpq import library (.lib/.a)")
if(OPENADS_LIBPQ_INCLUDE AND OPENADS_LIBPQ_LIBRARY)
set(_openads_pg_inc "${OPENADS_LIBPQ_INCLUDE}")
set(_openads_pg_lib "${OPENADS_LIBPQ_LIBRARY}")
endif()
if(NOT _openads_pg_lib)
if(DEFINED ENV{OPENADS_LIBPQ_LIBRARY})
set(_openads_pg_lib "$ENV{OPENADS_LIBPQ_LIBRARY}")
endif()
if(DEFINED ENV{OPENADS_LIBPQ_INCLUDE})
set(_openads_pg_inc "$ENV{OPENADS_LIBPQ_INCLUDE}")
endif()
endif()
if(NOT _openads_pg_lib OR NOT _openads_pg_inc)
if(DEFINED ENV{OPENADS_TOOLCHAIN_ROOT})
set(_openads_toolchain_root "$ENV{OPENADS_TOOLCHAIN_ROOT}")
elseif(DEFINED OPENADS_TOOLCHAIN_ROOT)
set(_openads_toolchain_root "${OPENADS_TOOLCHAIN_ROOT}")
endif()
if(_openads_toolchain_root)
if(NOT _openads_pg_inc)
find_path(_openads_pg_inc libpq-fe.h
PATHS "${_openads_toolchain_root}/pgsql/include"
NO_DEFAULT_PATH)
endif()
if(NOT _openads_pg_lib)
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
find_library(_openads_pg_lib NAMES libpq pq
PATHS "${_openads_toolchain_root}/libpq/x86"
"${_openads_toolchain_root}/libpq/x86/lib"
NO_DEFAULT_PATH)
else()
find_library(_openads_pg_lib NAMES pq libpq
PATHS "${_openads_toolchain_root}/pgsql/lib"
NO_DEFAULT_PATH)
endif()
endif()
endif()
endif()
if(_openads_pg_inc AND _openads_pg_lib)
add_library(openads_libpq INTERFACE)
target_include_directories(openads_libpq INTERFACE "${_openads_pg_inc}")
target_link_libraries(openads_libpq INTERFACE "${_openads_pg_lib}")
set(_openads_pg_linked TRUE)
message(STATUS "OpenADS: PostgreSQL backend (libpq: ${_openads_pg_lib})")
endif()
if(NOT _openads_pg_linked)
find_package(PostgreSQL REQUIRED)
add_library(openads_libpq INTERFACE)
target_include_directories(openads_libpq INTERFACE "${PostgreSQL_INCLUDE_DIRS}")
target_link_libraries(openads_libpq INTERFACE PostgreSQL::PostgreSQL)
message(STATUS "OpenADS: PostgreSQL backend (libpq via find_package)")
endif()
endif()

if(OPENADS_WITH_MARIADB)
set(_openads_maria_linked FALSE)
set(OPENADS_LIBMARIADB_INCLUDE "" CACHE PATH "Directory containing mysql.h")
set(OPENADS_LIBMARIADB_LIBRARY "" CACHE FILEPATH "libmariadb import library (.lib/.a)")
if(OPENADS_LIBMARIADB_INCLUDE AND OPENADS_LIBMARIADB_LIBRARY)
set(_openads_maria_inc "${OPENADS_LIBMARIADB_INCLUDE}")
set(_openads_maria_lib "${OPENADS_LIBMARIADB_LIBRARY}")
endif()
if(NOT _openads_maria_lib)
if(DEFINED ENV{OPENADS_LIBMARIADB_LIBRARY})
set(_openads_maria_lib "$ENV{OPENADS_LIBMARIADB_LIBRARY}")
endif()
if(DEFINED ENV{OPENADS_LIBMARIADB_INCLUDE})
set(_openads_maria_inc "$ENV{OPENADS_LIBMARIADB_INCLUDE}")
endif()
endif()
if(NOT _openads_maria_lib OR NOT _openads_maria_inc)
if(DEFINED ENV{OPENADS_TOOLCHAIN_ROOT})
set(_openads_toolchain_root "$ENV{OPENADS_TOOLCHAIN_ROOT}")
elseif(DEFINED OPENADS_TOOLCHAIN_ROOT)
set(_openads_toolchain_root "${OPENADS_TOOLCHAIN_ROOT}")
endif()
if(_openads_toolchain_root)
if(NOT _openads_maria_inc)
find_path(_openads_maria_inc mysql.h
PATHS "${_openads_toolchain_root}/mariadb/include"
NO_DEFAULT_PATH)
endif()
if(NOT _openads_maria_lib)
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
find_library(_openads_maria_lib NAMES libmariadb
PATHS "${_openads_toolchain_root}/mariadb/lib"
NO_DEFAULT_PATH)
else()
find_library(_openads_maria_lib NAMES libmariadb64 libmariadb
PATHS "${_openads_toolchain_root}/mariadb/lib"
NO_DEFAULT_PATH)
endif()
endif()
endif()
endif()
if(_openads_maria_inc AND _openads_maria_lib)
add_library(openads_libmariadb INTERFACE)
target_include_directories(openads_libmariadb INTERFACE "${_openads_maria_inc}")
target_link_libraries(openads_libmariadb INTERFACE "${_openads_maria_lib}")
set(_openads_maria_linked TRUE)
message(STATUS "OpenADS: MariaDB backend (libmariadb: ${_openads_maria_lib})")
endif()
if(NOT _openads_maria_linked)
message(FATAL_ERROR "OPENADS_WITH_MARIADB=ON but libmariadb was not found")
endif()
endif()

if(MSVC)
add_compile_options(/W4 /permissive-)
add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
if(OPENADS_WARNINGS_AS_ERRORS)
add_compile_options(/WX)
endif()
elseif(WIN32 AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
# MinGW/winlibs: static link toolchain runtime; libpq.dll still loads at runtime.
add_link_options(-static)
else()
add_compile_options(-Wall -Wextra -Wpedantic -Wshadow -Wconversion)
# _CRT_SECURE_NO_WARNINGS: needed when clang-cl targets MSVC CRT on Windows;
Expand Down
39 changes: 39 additions & 0 deletions docs/OPENADS_PLUS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# OpenADS Plus — PostgreSQL

Extensão aditiva do [OpenADS](https://github.com/FiveTechSoft/OpenADS): tabelas PostgreSQL atrás da ABI ACE. DBF e wire inalterados.

## Deploy rápido

```bat
set OPENADS_TOOLCHAIN_ROOT=<dir com MSVC e pgsql\include/lib>
tools\scripts\build_nmake_postgres.bat
```

Saída: `build\pg\src\openace32.dll` — copiar para a pasta do `.exe` Harbour antes de outra `ace*.dll`.

## Conexão

`AdsConnect60("postgresql://user:pass@host:5432/dbname")`

## Teste ponta a ponta

```bat
set OPENADS_TEST_PG_URI=postgresql://user:pass@127.0.0.1:5432/testdb
build\pg\tests\openads_unit_tests.exe --test-case="*postgresql*"
```

O teste cria/derruba a tabela `clientes`, insere 3 linhas e valida navegação + SEEK pela ABI. Sem URI definida, os casos E2E fazem SKIP (CI não quebra).

## Segurança

- Nomes de tabela/coluna: só identificadores ASCII seguros (`[A-Za-z0-9_]`).
- Valores de SEEK e chaves: parâmetros preparados (`$1`), nunca concatenados.
- URI montada em runtime no app — sem paths hardcoded no código.

## Capacidades

| Recurso | Status |
|---------|--------|
| Read + navegação | Sim |
| SEEK por coluna | Sim |
| Write | Planejado |
Loading
Loading