ďťż
 
libpq i procedury ďťż
 
libpq i procedury
Zobacz wiadomości
 
Cytat
A gdyby tak się wedrzeć na umysłów górę, / Gdyby stanąć na ludzkich myśli piramidzie, / I przebić czołem przesądów chmurę, / I być najwyższą myślą wcieloną. . . Juliusz Słowacki, Kordian
Indeks BCB i MySQL subiekt gt fototapeta
 
  Witamy

libpq i procedury



Maciej Piekielniak - 01-04-2006 00:19
libpq i procedury
  Witam

W większości książek i materiałów można znaleźć, że funkcje
postgresql można tworzyć w językach C, plpgsql, sql itd. Standardowo
pisane funkcje w C służą głównie do obróbki przekazanych danych
do funkcji. Co jednak zrobić gdy np bibloteka napisana w C jest
podczepiona do funkcji i prócz obróbki danych/wyliczeń ma np.
zrobić update wierszy? Służy do tego oczywiście funkcja PQexec z
libpq-fe.h, ale jednym z parametrów przekazywanych do niej jest
identyfikator połączenia tworzony przez PQconnectdb() i zamykany
przez PQfinish().
I tu jest problem, z jednej strony muszę mieć identyfikator
połączenia, z drugiej gdy go zamknę przez PQfinish() program traci
połączenie z bazą ponieważ funkcja zamyka połączenie.

np:

wywoluje SELECT funkcja();

CREATE OR REPLACE FUNCTION funkcja()
RETURNS INT4 AS
'/lib/fun.so' LANGUAGE 'c';

fun.c:

#include <stdio.h>
#include <stdlib.h>
#include "libpq-fe.h"

int fun()
{
char zap[256];
PGconn *conn;
PGresult *wynik;

conn = PQconnectdb("dbname=bazka user=postgres");

sprintf(zap,"UPDATE tabelka SET jakiespole=%d",1);
wynik = PQexec(conn,zap);
PQclear(wynik);

PQfinish(conn);
return 0;
}





hubert depesz lubaczewski - 02-04-2006 00:10

  Maciej Piekielniak wrote:
> wywoluje SELECT funkcja();
> CREATE OR REPLACE FUNCTION funkcja()
> RETURNS INT4 AS
> '/lib/fun.so' LANGUAGE 'c';
> fun.c:
> #include <stdio.h>
> #include <stdlib.h>
> #include "libpq-fe.h"
> conn = PQconnectdb("dbname=bazka user=postgres");

pisząc funkcje w c nie łącz się do bazy przez libpq. używaj interfejsu SPI.
więcej o tym - w docach, albo przejrzyj źródła programów w conribie.

depesz




max - 02-04-2006 00:10

  hubert depesz lubaczewski napisał(a):
> Maciej Piekielniak wrote:
>> wywoluje SELECT funkcja();
>> CREATE OR REPLACE FUNCTION funkcja()
>> RETURNS INT4 AS
>> '/lib/fun.so' LANGUAGE 'c';
>> fun.c:
>> #include <stdio.h>
>> #include <stdlib.h>
>> #include "libpq-fe.h"
>> conn = PQconnectdb("dbname=bazka user=postgres");

W sumie to ciekawy pomysł :)
Wkapilowywać w biblioteke parametry polaczenia ;) i otwierac kolejne
polaczenie.

Warto zajrzec do prostych przykładów w katalogu "contrib"
Ja tam sie wzorowałem na tym i działa.




Maciej Piekielniak - 02-04-2006 00:11

  Ok, cos tam znalazlem ale strasznie zagmatwane w porownaniu do libpq.
Jakies SPITupleTable,TupleDesc,HeapTuple,elog,..
Praktycznie procz oryginalnej dokumentacji niewiele jest.

Na zakonczenie jak byscie to przerobili?

for(i=0;i<PQntuples(wynik);i++)
{
sprintf(zmienna1,"AAA %s\n",PQgetvalue(wynik,i,0));
sprintf(zmienna2,"BBB %s\n",PQgetvalue(wynik,i,0));
}





Maciej Piekielniak - 02-04-2006 00:11

  Moze inaczej, po pierwsze czy poprawny sposób kompilowania to
(podczas tworzenia funkcji odpalajacej ta bibloteke dostalem blad
ERROR: could not load library "/lib/ala.so": /lib/ala.so: undefined
symbol: SPI_EXEC)):

cc -I/usr/include/postgresql/server/ -fpic -c ala.c
cc -shared -o ala.so ala.o -lpq

i jak tu uzupelnic? :)

#include <stdio.h>
#include <stdlib.h>
#include "executor/spi.h"

int ala()
{
char zap[256];
char komenda[256];
int i,j,ret,ret_k;

if(ret=SPI_connect()!=SPI_OK_CONNECT)
elog(ERROR, "ERROR: %d",ret);

strcpy(zap,"SELECT * from komputer;");
ret = SPI_EXEC(zap,0);
ret_k=SPI_processed;

if(ret == SPI_OK_SELECT && ret_k>0)
{
// Jak tu wyswietlic wszystkie wiersze lub kolumny
// lub wszystkie wiersze z jedna kolumna
}

SPI_finish();
return 0;
}




Ronald Kuczek - 03-04-2006 00:07

  Użytkownik Maciej Piekielniak napisał:
> Moze inaczej, po pierwsze czy poprawny sposób kompilowania to
> (podczas tworzenia funkcji odpalajacej ta bibloteke dostalem blad
> ERROR: could not load library "/lib/ala.so": /lib/ala.so: undefined
> symbol: SPI_EXEC)):
>
> cc -I/usr/include/postgresql/server/ -fpic -c ala.c
> cc -shared -o ala.so ala.o -lpq
>
> i jak tu uzupelnic? :)
Ech.. Maćku, skorzystaj z Makefile.
Załóżmy,że kompiluję bibliotekę mojarzezba.c umieszczoną w source_tree
postgresa w katalogu contrib/mojkatalog
#
#

subdir = contrib/mojkatalog
top_builddir = ../..
include $(top_builddir)/src/Makefile.global

OBJS = mojarzezba.o
#DOCS = README.mojarzezba
#SQLS = $(OBJS:.o=.sql)
#EXAMPLES= $(OBJS:.o=.example)
MODS = $(OBJS:.o=$(DLSUFFIX))

override CPPFLAGS := -I$(srcdir) $(CPPFLAGS)
override CFLAGS += $(CFLAGS_SL)

ifdef REFINT_VERBOSE
override CPPFLAGS+= -DREFINT_VERBOSE
endif

override DLLLIBS := $(BE_DLLLIBS) $(DLLLIBS)

all: $(MODS) $(SQLS)

%.sql: %.sql.in
sed -e 's:MODULE_PATHNAME:$(libdir)/contrib/$(@:.sql=$(DLSUFFIX)):g' <
$< > $@

install: all installdirs
for inst_file in $(SQLS); do \
$(INSTALL_DATA) $$inst_file $(datadir)/contrib || exit; \
done
for inst_file in $(MODS); do \
$(INSTALL_SHLIB) $$inst_file $(libdir)/contrib || exit; \
done
for inst_file in $(EXAMPLES) README.mojarzezba; do \
$(INSTALL_DATA) $$inst_file $(docdir)/contrib/mojkatalog || exit; \
done

installdirs:
$(mkinstalldirs) $(datadir)/contrib $(libdir)/contrib $(docdir)/contrib/spi

uninstall:
rm -f $(addprefix $(datadir)/contrib/, $(SQLS)) \
$(addprefix $(libdir)/contrib/, $(MODS)) \
$(addprefix $(docdir)/contrib/mojkatalog/, $(EXAMPLES) README.mojarzezba)

clean distclean maintainer-clean:
rm -f $(MODS) $(SQLS) $(OBJS)

depend dep:
$(CC) -MM -MG $(CFLAGS) *.c > depend

ifeq (depend,$(wildcard depend))
include depend
endif

> #include <stdio.h>
> #include <stdlib.h>
> #include "executor/spi.h"
>
> int ala()
> {
> char zap[256];
> char komenda[256];
> int i,j,ret,ret_k;
>
> if(ret=SPI_connect()!=SPI_OK_CONNECT)
> elog(ERROR, "ERROR: %d",ret);
>
>
> strcpy(zap,"SELECT * from komputer;");
> ret = SPI_EXEC(zap,0);
> ret_k=SPI_processed;
>
> if(ret == SPI_OK_SELECT && ret_k>0)
> {
> // Jak tu wyswietlic wszystkie wiersze lub kolumny
> // lub wszystkie wiersze z jedna kolumna
> }
>
> SPI_finish();
> return 0;
> }
>

W dokumentacji jest przykład, zerknij (40.1), nie doczytałeś o SPI_getvalue.
Przykład jest dość jasny, nie będę go tutaj powielał.

Pozdrawiam
Rony
  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • effulla.pev.pl
  • comp
    [oracle] czy da =?ISO-8859-2?Q?si=EA_z_poziomu_procedury_?==?ISO-8859-2?Q?zrobi=E6_kopi=EA_zapasow=B1=3F?= MSSQL 2005 i uruchamianie procedury o =?ISO-8859-2?Q?okre=B6lone?==?ISO-8859-2?Q?j_godzinie?= [MS SQL 2000/2005] Procedura z dynamicznym SQL =?iso-8859-2?q?Procedura_sk=B3adowalna_wywo=B3ywana_o_okreslo nej_godzinie?= [ORACLE] Stored Procedures - jaki typ danych przy dostępnie poprzez ADO? =?iso-8859-2?q?[Mysql_5=2E0]_Wywo=B3ywanie_procedury_jako_parametr_funkcji?= [MySQL5] problem z zastosowanie funkcji, procedury w celu unikniecia powtórzeń kodu w zapytaniach =?iso-8859-2?q?wysy=B3anie_emaila_za_pomoca_procedury_skladow anej_Oracle?= =?iso-8859-2?Q?=5Boracle_pl/sql=5D_r=F3=BFnice_w_tworzeniu_procedur?= =?iso-8859-2?q?Nazwa_Tabeli_jako_parametr_w_procedurze_sk=B3a dowanej?=
  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • natalia97.htw.pl
  • Cytat

    Decede mihi sole - nie zasłaniaj mi słonca.
    Gdy kogoś kochasz, jesteś jak stworzyciel świata - na cokolwiek spojrzysz, nabiera to kształtu, wypełnia się barwą, światłem. Powietrze przytula się do ciebie, choćby był mróz, a ty masz w sobie tyle radości, że musisz ją rozdawać wokoło, bo się w tobie nie mieści
    Hoc fac - tak czyń.
    A tergo - od tyłu; z tyłu.
    I czarne włosy posiwieją. Safona

    Valid HTML 4.01 Transitional

    Free website template provided by freeweblooks.com