lumnik. / scenarios All scenarios · Français

Firebird (Delphi): refused over JDBC, read through its export

Goal Read a Delphi application's Firebird database, and be told when an article falls under its reorder threshold.

A Delphi stock application on Firebird 5: 40 articles, a WIN1252 database.

manifests/10-firebird-jdbc.yaml
# The first attempt: read the Firebird database directly, as jdbc-generic reads PostgreSQL.apiVersion: connectors.lumnik.io/v1kind: Connectormetadata:  name: scenario-fb-jdbc-a  connector_type: jdbc-generic  scopes: [stock-a]spec:  connection:    url: jdbc:firebirdsql://host.docker.internal:3061//var/lib/firebird/data/gestock.fdb    user: SYSDBA    password_env: SCENARIO_FIREBIRD_PASSWORD  source:    tables:      - name: ARTICLES        mode: full        pk_columns: [ART_ID]        target: articles_a
manifests/lab-docker-compose.yml
# The Delphi stock application's database: Firebird 5, a WIN1252 database (lab/init.sql).name: scenario-firebird-stockservices:  firebird:    image: firebirdsql/firebird:5.0.1    environment:      FIREBIRD_ROOT_PASSWORD: masterkey   # the lab's own; Firebird's historical default    ports: ["127.0.0.1:${FIREBIRD_PORT:-3061}:3050"]    volumes:      - ../lab:/lab:ro      - ../manifests:/manifests:ro   # export-articles.sql, the scheduled export
manifests/export-articles.sql
-- The scheduled export, run by isql next to the Delphi application.-- rm -f /exports/articles.csv && isql -user SYSDBA -ch WIN1252 -q -i export-articles.sql gestock.fdbSET HEADING OFF;SET BAIL ON;OUTPUT /exports/articles.csv;             -- appends: the job removes the previous file firstSELECT 'art_id;ref;libelle;qte_stock;seuil;prix_ht;date_maj' FROM RDB$DATABASE;   -- padded too: the hub trims itSELECT ART_ID || ';' || REF || ';' || COALESCE(LIBELLE, '') || ';' || QTE_STOCK || ';' || SEUIL || ';' || PRIX_HT       || ';' || DATE_MAJ  FROM ARTICLES ORDER BY ART_ID;OUTPUT;
manifests/20-articles.yaml
apiVersion: connectors.lumnik.io/v1kind: Connectormetadata:  name: scenario-fb-articles-a  connector_type: csv-file  scopes: [stock-a]spec:  transport:    kind: local    path: /tmp/lumnik-scenario/firebird-delphi-stock/a/articles.csv   # the share the export writes to  parser:    delimiter: ";"    encoding: windows-1252          # the database's character set, as isql -ch WIN1252 writes it  after_process: none  mapping:    cell:      - clean: { columns: [date_maj], strip: true }   # isql pads every line to the expression's width      - parse-number: { column: qte_stock }      - parse-number: { column: seuil }      - parse-number: { column: prix_ht }      - parse-date: { column: date_maj, formats: ["yyyy-MM-dd"] }
manifests/30-below-threshold.yaml
apiVersion: apps.lumnik.io/v1kind: Processmetadata:  name: scenario-fb-reorder-aspec:  scope: stock-a  on: { event: data.row.changed, table: connector.t_scenario_fb_articles_a }  when:    - "qte_stock<{seuil}"            # the stock fell under the article's own threshold  emit:    type: decision.reorder-a    message: "{ref} {libelle}: {qte_stock} in stock, threshold {seuil}"    key: ref
$ lm connector run scenario-fb-articles-a
run scheduled: e03443a2-eaf1-4cfc-9a68-b26d628acc31

$ lm run get e03443a2-eaf1-4cfc-9a68-b26d628acc31
ID        CONNECTOR               ENDPOINT  STATUS     IN  OUT  SKIPPED  DEAD-LETTERS  STARTED           ENDED             EVALUATED
e03443a2  scenario-fb-articles-a  default   Completed  40  40   0        0             2026-11-06 16:51  2026-11-06 16:51  yes

$ lm inbox --process scenario-fb-reorder-a
ID     WHEN      PROCESS                MESSAGE                                                       ENTITY_KEY
24402  just now  scenario-fb-reorder-a  ART-0023 Pistolet à mastic: 4 in stock, threshold 6           ART-0023
24401  just now  scenario-fb-reorder-a  ART-0012 Vis à bois 4x40 (boîte): 7 in stock, threshold 9     ART-0012
24400  just now  scenario-fb-reorder-a  ART-0002 Tournevis cruciforme PH2: 17 in stock, threshold 19  ART-0002
24389  just now  scenario-fb-reorder-a  ART-0023 Pistolet à mastic: 4 in stock, threshold 6           ART-0023
24388  just now  scenario-fb-reorder-a  ART-0012 Vis à bois 4x40 (boîte): 7 in stock, threshold 9     ART-0012
24387  just now  scenario-fb-reorder-a  ART-0002 Tournevis cruciforme PH2: 17 in stock, threshold 19  ART-0002
24330  1h        scenario-fb-reorder-a  ART-0023 Pistolet à mastic: 4 in stock, threshold 6           ART-0023
24329  1h        scenario-fb-reorder-a  ART-0012 Vis à bois 4x40 (boîte): 7 in stock, threshold 9     ART-0012
24328  1h        scenario-fb-reorder-a  ART-0002 Tournevis cruciforme PH2: 17 in stock, threshold 19  ART-0002

Limits

  • This hub carries the oracle and postgres dialects (Pro); an Open hub lists postgres alone.
  • The export is a daily file: a sale is seen at the next export, not at the till.
  • Synthetic articles, stocks and prices.

Stock · Delphi

The stock lives in a Delphi application.

Its database is Firebird.

40 articles, WIN1252, Firebird 5

The refusal

No Firebird dialect.

  • The apply refuses, and names what is installed.
  • Until a customer needs one, the export does.

What is not changed

The Delphi application stays as it is.

  • The isql export it already schedules.
  • WIN1252 accents, padded lines.

What had to be written

encoding: windows-1252
when: ["qte_stock<{seuil}"]

One encoding, one condition between two columns.

  • csv-file: the export as it comes.
  • A Process: one decision per article.

What was found

A padded header became a column name.

  • The hub now trims it (#1853).
  • isql's OUTPUT appends: the job removes the file first.

Try it

The scenario replays locally.

Every step is published with its output.

This scenario runs on lumnik Open, free and open source.

Try lumnik Open →