FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin for Harbour/xHarbour DBF Microservice via HTTP: Proof of Concept for Direct JSON Access
Posts: 6983
Joined: Fri Oct 07, 2005 07:07 PM
DBF Microservice via HTTP: Proof of Concept for Direct JSON Access
Posted: Thu Jul 03, 2025 07:43 AM
Hello friends,

I am now trying to convert my microservice, which previously worked via request and response JSON files, to an HTTP server using Harbour.
I'm curious to see the results.
Here is a first draft - I will try now testing:
//============================================================================//
//                                                                            //
//                       HARBOUR MICROSERVICE – HTTP JSON                     //
//                                                                            //
//    Ziel:                                                                  //
//      - Microservice, der eine DBF-Datei (KUNDEN.DBF) mit CDX-Index       //
//        ΓΌber einen lokalen HTTP-Endpunkt abfragt                          //
//      - Bei GET-Request wie                                                //
//          http://localhost:9090/search?name=ABCD                          //
//        werden alle Kunden geliefert, deren Name mit "ABCD" beginnt      //
//                                                                            //
//    Sicherheit:                                                            //
//      - Der Server bindet NUR auf 127.0.0.1 (localhost)                   //
//        β†’ keine Verbindung von außen mΓΆglich                              //
//                                                                            //
//============================================================================//

#include "hbcompat.ch"
#include "fileio.ch"
#include "hbjson.ch"

REQUEST DBFCDX
REQUEST HB_INET
REQUEST HB_SOCKET

FUNCTION Main()
   LOCAL oSocket, oListen, cRequest, cName, hResult, aResult := {}
   LOCAL cLine, cParam, aParam, cKey
   LOCAL cDBF := "x:\xwhdaten\DATAWIN\KUNDEN.dbf"

   // Starte Server: lausche NUR auf 127.0.0.1:9090 β†’ nur lokal erreichbar!
   oListen := hb_inetCreate()
   IF ! hb_inetBind(oListen, 9090, "127.0.0.1")
      ? "Fehler: Port 9090 ist nicht verfΓΌgbar oder bereits belegt."
      RETURN
   ENDIF
   ? "Microservice lΓ€uft lokal auf http://127.0.0.1:9090"

   // Datenbank vorbereiten (KUNDEN.DBF mit Index KU_NAME)
   USE (cDBF) ALIAS kunden NEW SHARED VIA "DBFCDX"
   SET INDEX TO x:\xwhdaten\DATAWIN\KUNDEN.CDX
   ORDSETFOCUS("KU_NAME")  // Suchindex

   // Endlosschleife: Anfragen verarbeiten
   DO WHILE .T.
      oSocket := hb_inetAccept(oListen)
      IF oSocket == NIL
         LOOP
      ENDIF

      cRequest := hb_inetRecvLine(oSocket)  // z.β€―B. "GET /search?name=ABCD HTTP/1.1"
      IF cRequest == NIL
         hb_inetClose(oSocket)
         LOOP
      ENDIF

      IF "GET /search?" $ cRequest
         // ==== Anfrage parsen ====
         cParam := StrToken(cRequest, "?", 2)                 // hole "name=ABCD HTTP/1.1"
         aParam := hb_aTokens(StrToken(cParam, " ", 1), "&")  // zerlege in name=ABCD, ...

         cName := ""  // Suche nach Name initialisieren
         FOR EACH cLine IN aParam
            a := hb_aTokens(cLine, "=")
            IF Lower(a[1]) == "name"
               cName := Upper(UrlDecode(a[2]))
            ENDIF
         NEXT

         // ==== Suche starten ====
         IF !Empty(cName)
            DBSEEK(cName)
            DO WHILE !EOF() .AND. Left(Upper(TRIM(kunden->name)), Len(cName)) == cName
               AAdd(aResult, { ;
                  "name" => kunden->name, ;
                  "plz"  => kunden->plz, ;
                  "ort"  => kunden->ort ;
               })
               DBSKIP()
            ENDDO
         ENDIF

         // ==== Ergebnis vorbereiten ====
         hResult := { ;
            "status"  => "ok", ;
            "query"   => cName, ;
            "results" => aResult }

         // ==== JSON-Antwort senden ====
         hb_inetSend(oSocket, "HTTP/1.1 200 OK" + CRLF )
         hb_inetSend(oSocket, "Content-Type: application/json" + CRLF + CRLF )
         hb_inetSend(oSocket, hb_jsonEncode(hResult) + CRLF )
      ELSE
         // 404 bei nicht unterstΓΌtztem Request
         hb_inetSend(oSocket, "HTTP/1.1 404 Not Found" + CRLF + CRLF )
      ENDIF

      // Verbindung schließen und Daten zurücksetzen
      hb_inetClose(oSocket)
      aResult := {}  // Ergebnisse fΓΌr nΓ€chsten Request leeren
   ENDDO

   CLOSE kunden
RETURN NIL

// Hilfsfunktion: URL-Parameter dekodieren (z.β€―B. %20 β†’ Leerzeichen)
STATIC FUNCTION UrlDecode( c )
   LOCAL i, cOut := "", nLen := Len(c), nChar
   i := 1
   DO WHILE i <= nLen
      IF SubStr(c, i, 1) == "%"
         nChar := Val( "0x" + SubStr(c, i+1, 2) )
         cOut += Chr(nChar)
         i += 3
      ELSE
         cOut += SubStr(c, i, 1)
         i++
      ENDIF
   ENDDO
RETURN cOut

Best regards,
Otto
Posts: 1816
Joined: Wed Oct 26, 2005 02:49 PM
Re: DBF Microservice via HTTP: Proof of Concept for Direct JSON Access
Posted: Fri Jul 04, 2025 12:57 PM
Hola Otto buenos dΓ­as como estas?

Una pregunta este ejemplo funciona para xharbour? ya que intentamos compilar y salen algunos errores...
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
?FiveWin for xHarbour 25.01 64bits - Jan. 2025   Harbour development power  β”‚β–„
?(c) FiveTech 1993-2025 for Microsoft Windows 9X/NT/200X/ME/XP/Vista/7/8/10 β”‚β–ˆ
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜?
Β  β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€?
Compiling...
C:\xHar2501_64\bin\harbour leandro7 /n /d__64__ /iC:\fwh64_2501\include;C:\xHar2501_64\include /w /p
xHarbour 1.3.1 Intl. (SimpLex) (Build 20250219)
Copyright 1999-2024, http://www.xharbour.org http://www.harbour-project.org/
Compiling 'leandro7.prg' and generating preprocessed output to 'leandro7.ppo'...
leandro7.prg(20) Error F0029  Can't open #include file: 'hbjson.ch'
* Compiling errors *
Saludos
LEANDRO AREVALO
BogotΓ‘ (Colombia)
https://hymlyma.com
https://hymplus.com/
leandroalfonso111@gmail.com
leandroalfonso111@hotmail.com

[ Turbo Incremental Link64 6.98 Embarcadero 7.70 ] [ FiveWin 25.01 ] [ xHarbour 64 bits) ]
Posts: 6983
Joined: Fri Oct 07, 2005 07:07 PM
Re: DBF Microservice via HTTP: Proof of Concept for Direct JSON Access
Posted: Fri Jul 04, 2025 01:10 PM

Hello Leandro,

The code is technically correct for Harbour – it uses modern, modular features.

With xHarbour, it's not directly possible because hbjson.ch, hb_inet*, and hash functions are missing.

Recommendation: If possible, compile the microservice using Harbour – since it doesn’t use any GUI or specific FiveWin elements, all you need is the compiler with HB_INET and HB_JSON enabled.

Best regards,

Otto

Continue the discussion