FiveTech_ERP: driver de datos opcional "hdbc" (RDDHDBC sobre MariaDB) - #26
FiveTech_ERP: driver de datos opcional "hdbc" (RDDHDBC sobre MariaDB)#26russimicro wants to merge 10 commits into
Conversation
Extends the existing pluggable data layer (json/dbfcdx/openads in erp_db.prg) with a fourth driver, backed by RDDHDBC — a third-party RDD (Manu Exposito) that maps standard xBase RDD calls onto MariaDB. It fits cleanly because erp_db.prg already talks to every backend through plain RDD verbs (dbUseArea/dbGoTop/dbSkip/FieldGet/dbAppend/RLock/FieldPut/ dbDelete/dbCommit) — never hand-built SQL — which is exactly the level RDDHDBC operates at; erp_http.prg's driver dispatch needs no changes. This ships no third-party code: the new branch in ErpDbConfig/ErpDbOpen/ ErpDbStatus only compiles in when the build defines HB_WITH_HDBC, and only calls a function (ErpDbHdbcUserConnect) that each user supplies themselves, in their own separate .prg, using their own licensed HDBC package — mirroring the same "compiles clean without it" contract build_win64.bat already uses for OpenADS's ace64.dll, adapted for a statically-linked lib: hdbctools.lib and HDBC_CONNECT_PRG are both opt-in build inputs; without them the build is unchanged. See docs/hdbc-driver.md for the full contract, how to enable it, and known limits (no auto-create, process-local record locks) worth validating against your own RDDHDBC version. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
well-trodden problem, not a blocker for the hdbc driver Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…sql) Replaces the vague "migration is a well-trodden path" doc note with an actual, working generator: ErpDbHdbcSchemaSql() in erp_db.prg reuses the same JSON-schema inference dbfcdx already relies on (ErpDbInferSchema) to emit one "CREATE TABLE IF NOT EXISTS" per data.* dataset, plus the _h_rowid_/deleted_at bookkeeping columns RDDHDBC tables need. It only ever produces text — no HDBC dependency, no live connection, nothing executed against any database — exposed at GET /api/db/schema-sql (same session auth as the existing /api/db/status) for the user to review and run by hand. RDDHDBC's own index-metadata table is explicitly out of scope here; that's on RDDHDBC's own setup docs. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Actualización: generador de esquema propio (no un migrador externo)El mensaje anterior de este PR mencionaba de forma vaga que "existe tooling
La tabla propia de metadatos de índices de RDDHDBC queda explícitamente Verificado: 🤖 Generado con Claude Code |
ErpDbReadRows()/ErpDbApply() require <name>.map.json to exist before the hdbc driver can do anything; the schema generator was inferring it but never saving it, unlike the dbfcdx path it mirrors. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Small standalone page (own static file under www/, no build step) that reads/writes meta/app.json -> "database" through the existing admin-gated GET/POST /api/meta contract (same one the runtime form designer already uses) and shows GET /api/db/status. Lets you pick driver (json/dbfcdx/ openads/hdbc) and its host/port/dataPath/user/password without hand-editing JSON, and links to GET /api/db/schema-sql for the hdbc DDL preview. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Actualización: UI de configuración + validación end-to-end del esquema
🤖 Generado con Claude Code |
Found by actually running the generated DDL against a real MariaDB server: several demo dataset/field names (user, key, when, ...) are MariaDB reserved words and broke CREATE TABLE without quoting. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Both found by actually building and running this against a real MariaDB (own local RDDHDBC license, verified end-to-end: reads, add, update, delete all round-tripped correctly against real SQL data): 1. The RDD's registered name is "RDDHDBC", not "HDBC" — dbUseArea() was using the wrong string. Also drops the now-pointless top-of-file REQUEST: there's no linkable "RDDHDBC" function symbol to request; the RDD's registration module gets force-linked automatically because ErpDbHdbcUserConnect() (required by the contract) already calls one of its real public functions from the same compiled unit. 2. ErpDbApply()'s "delete not persisted" re-check via Deleted() right after dbDelete() is an OpenADS-specific workaround for a known quirk there; it produced false negatives on hdbc, where deletes persist correctly (deleted_at set, confirmed with direct SQL) even though Deleted() on the just-modified record can read back .F. before the next fetch. Scoped to driver == "openads" only. docs/hdbc-driver.md updated with what was actually verified. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Validado end-to-end contra una MariaDB real (entorno propio, no en este repo)Compilé este driver con mi propia licencia de RDDHDBC (fuera del repo) y lo
Resultado tras los fixes (verificado con SQL directo en paralelo):
🤖 Generado con Claude Code |
Makes the driver-config page reachable from the "PC" branch: this same portal already loads inside the exe's own embedded WebView2 via ZWEB_FRONT=portal, so this link surfaces there too, not just in a browser. Note: db-config.html itself ships in the companion "hdbc" driver PR (#26), not this one — the link 404s until that lands, same as any other cross-PR reference would. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
… folder Lets the "PC" branch reach db-config.html directly inside its own embedded WebView2 (ZWEB_FRONT=db-config.html) instead of only being reachable from a browser. Backward compatible: ZWEB_FRONT=web-vainilla / =portal (bundle folders, PR #24) still resolve to <name>/index.html exactly as before — only a value already ending in ".html" skips that suffix. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Alcanzable desde la rama PC tambiénCon el patrocinio del usuario: agregué en `Form1.prg` que `ZWEB_FRONT` acepte 🤖 Generado con Claude Code |
www/dashboard.html already had a driver select + host/port/dataPath/user/ password fields (shared with openads, same shape hdbc needs) — it just didn't list hdbc as an option. Adds the <option> and extends the existing openads visibility toggle to also show those fields for hdbc. The save handler already read all these fields generically, so this is UI-only. Heads up (documented in docs/hdbc-driver.md): dashboard.html is normally regenerated from FWH's login.prg by sync_meta.bat, so this two-line change needs to be mirrored in the FWH source to survive the next sync. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
confusing later error Navigating straight to /db-config.html without a session first made the initial GET /api/meta?key=app fail silently (message only shown, easy to miss); clicking Guardar afterwards then failed with the unrelated-looking "Todavia no cargo meta/app.json." Now hides the form and shows a direct link to /login as soon as either GET call reports not authenticated. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Resumen
erp_db.prgya tiene una capa de datos intercambiable (jsonpor defecto,dbfcdx,openads). Este PR agrega un cuarto driver,hdbc, respaldadopor RDDHDBC — un RDD de terceros (Manu Expósito) que traduce los verbos
xBase estándar a MariaDB.
Por qué encaja como RDD (y no como SQL crudo)
erp_db.prgya habla con cada backend exclusivamente a través de verbos RDDplanos —
dbUseArea / dbGoTop / dbSkip / FieldGet / dbAppend / RLock / FieldPut / dbDelete / dbCommit— nunca arma SQL a mano. RDDHDBC operaexactamente a ese nivel (
USE <tabla> VIA "HDBC"), así que el cambio espuramente aditivo: cero cambios en
erp_http.prg(su despachoif ErpDbDriver() != "json"ya es genérico) y cero cambios enErpDbReadRows/ErpDbApply.Qué NO incluye este PR (importante)
Este PR no distribuye, vincula ni referencia ningún código o nombre de
API de RDDHDBC/HDBC. Es software comercial de Manu Expósito con licencia
propia — conseguirlo y usarlo es un acuerdo entre cada usuario y él, igual
que con MariaDB.
ErpDbConfig/ErpDbOpen/ErpDbStatussolo compilacuando el build define
HB_WITH_HDBC.ErpDbHdbcUserConnect) que cada usuarioimplementa en su propio archivo aparte, con su propio paquete HDBC
licenciado — nunca parte de este repo.
build_win64.batsigue el mismo contrato "compila limpio sin ello" queya usa para
ace64.dllde OpenADS, adaptado para una lib estática:requiere
hdbctools.libpropia del usuario en%HBLIB%yHDBC_CONNECT_PRGapuntando a su conector. Sin ambos, el build esidéntico a hoy (verificado:
erp_db.prgcompila limpio con y sin-dHB_WITH_HDBCusando harbour.exe local).Detalle completo del contrato, cómo activarlo y límites conocidos (no
auto-crea tablas;
RLock()es por-proceso, no por-base) endocs/hdbc-driver.md.Verificación
🤖 Generado con Claude Code