Er zijn hier verschillende problemen.
Je kunt niet zomaar elke C-functie aanroepen vanuit SQL
Ten eerste kun je niet zomaar willekeurige functies vanuit SQL aanroepen, je moet de C-extensie-API's en macro's van PostgreSQL gebruiken; kijk naar de bestaande implementaties van SQL-aanroepbare functies in de bronnen voor voorbeelden.
U hoeft de kerncode meestal niet aan te passen, extensies zijn vaak voldoende
Ten tweede, als u functies wilt toevoegen aan de kern van PostgreSQL, moet u deze toevoegen aan src/include/catalog/pg_proc.h
dus ze worden gedefinieerd tijdens initdb
.
Het is echter veel beter om de juiste laadfaciliteiten voor extensies te gebruiken:
- http://www.postgresql.org/docs/ current/static/xfunc-c.html
- http://www.postgresql.org/docs/ current/static/extend-pgxs.html
Op deze manier kunt u LOAD
een uitbreidingsmodule, CREATE FUNCTION
de C functioneert volgens de documenten en roept ze op vanuit SQL.
In jouw specifieke geval lijkt het erop dat je doe moet de kerncodebase wijzigen, maar dit is vrij ongebruikelijk, dus ik bewaar dit advies voor anderen.
Een C-functie in de PostgreSQL-backend kan niet "rechtstreeks" worden aangeroepen vanuit een GUI
Je hebt een Java Swing GUI en je ziet op de een of andere manier een C-functie aanroepen in een ander proces, mogelijk zelfs op een andere host.
Dit zal om verschillende redenen niet werken, waaronder:
- Java kan C-functies niet rechtstreeks aanroepen zonder lijmcode zoals
JNI
ofJNA
. - Het is niet mogelijk om rechtstreeks een C-functie in een ander proces aan te roepen; je moet in plaats daarvan communicatie tussen processen gebruiken (gedeeld geheugen, buizen, sockets, gedeelde bestanden, enz.) om informatie uit te wisselen
- Terwijl je een Java-interpreter in de Pg-backend zou kunnen insluiten en de C-functie via JNI een beetje rechtstreeks zou kunnen aanroepen, echt wil niet proberen om een Swing GUI rechtstreeks vanuit een Pg-backend weer te geven.
Wat je nodig hebt, is een proces in meerdere fasen:
-
Verzamel de gegevens die u wilt vastleggen in de PostgreSQL-backend. Als u van plan bent toegang te krijgen via dezelfde verbinding waarmee deze is gemaakt, kunt u een gewone
palloc
gebruiken zou bufferen. Anders moet u een buffer uit het gedeelde geheugen toewijzen of gegevens uitwisselen met behulp van het bestandssysteem. -
Krijg toegang tot die gegevens vanuit een C-functie die is gemaakt met een SQL-aanroepbare interface volgens de documentatie van de C-extensiefunctie van PostgreSQL (hierboven)
-
Gebruik een PostgreSQL-verbinding om de gegevens van uw SQL-aanroepbare interfacefunctie naar uw Java-toepassing over te brengen. Decodeer het in uw applicatie en toon het zoals gewenst.
Als alternatief:
-
Vereist dat uw Java-programma, of een agent daarvoor, op hetzelfde systeem draait als de PostgreSQL-server en dat de agent bestanden schrijft op een locatie die naar Pg kan worden geschreven en die door uw programma kan worden gelezen.
-
Lees de bestanden met uw programma of zijn agent en verwerk ze voor weergave
Je zou Pg zelfs kunnen laten schrijven naar een socket waarop je programma luistert, maar ik raad dit niet aan omdat een blokkade in je programma prestatieproblemen zou veroorzaken in PostgreSQL.