Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit41b8c2c

Browse files
committed
As proposed,
following is the patch to libpq's large object interface that removes the requirement to include fmgr.h into fe-lobj.c. The large object interface now ask's the backend to tell the OID's of all the required functions in pg_proc.From: wieck@sapserv.debis.de (Jan Wieck)
1 parent2bdded3 commit41b8c2c

File tree

3 files changed

+237
-12
lines changed

3 files changed

+237
-12
lines changed

‎src/interfaces/libpq/fe-connect.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.17 1996/11/10 03:06:36 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.18 1996/11/11 12:16:54 scrappy Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -192,6 +192,7 @@ PQconnectdb(const char *conninfo)
192192
conn->Pfdebug=NULL;
193193
conn->port=NULL;
194194
conn->notifyList=DLNewList();
195+
conn->lobjfuncs=NULL;
195196

196197
conn->pghost=strdup(conninfo_getval("host"));
197198
conn->pgport=strdup(conninfo_getval("port"));
@@ -299,6 +300,7 @@ PQsetdb(const char *pghost, const char* pgport, const char* pgoptions, const cha
299300
conn->Pfdebug=NULL;
300301
conn->port=NULL;
301302
conn->notifyList=DLNewList();
303+
conn->lobjfuncs=NULL;
302304

303305
if (!pghost||pghost[0]=='\0') {
304306
if (!(tmp=getenv("PGHOST"))) {
@@ -519,6 +521,7 @@ freePGconn(PGconn *conn)
519521
if (conn->dbName)free(conn->dbName);
520522
if (conn->pguser)free(conn->pguser);
521523
if (conn->notifyList)DLFreeList(conn->notifyList);
524+
if (conn->lobjfuncs)free(conn->lobjfuncs);
522525
free(conn);
523526
}
524527

‎src/interfaces/libpq/fe-lobj.c

Lines changed: 220 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-lobj.c,v 1.3 1996/11/08 06:02:28 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-lobj.c,v 1.4 1996/11/11 12:16:56 scrappy Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -18,7 +18,6 @@
1818
#include<sys/types.h>
1919
#include"postgres.h"
2020
#include"libpq-fe.h"
21-
#include"fmgr.h"
2221
#include"libpq/libpq-fs.h"
2322

2423
#ifndefMAXPATHLEN
@@ -27,6 +26,8 @@
2726

2827
#defineLO_BUFSIZE 1024
2928

29+
staticintlo_initialize(PGconn*conn);
30+
3031
/*
3132
* lo_open
3233
* opens an existing large object
@@ -49,8 +50,14 @@ lo_open(PGconn* conn, Oid lobjId, int mode)
4950
argv[1].isint=1;
5051
argv[1].len=4;
5152
argv[1].u.integer=mode;
53+
54+
if(conn->lobjfuncs== (PGlobjfuncs*)NULL) {
55+
if(lo_initialize(conn)<0) {
56+
return-1;
57+
}
58+
}
5259

53-
res=PQfn(conn,F_LO_OPEN,&fd,&result_len,1,argv,2);
60+
res=PQfn(conn,conn->lobjfuncs->fn_lo_open,&fd,&result_len,1,argv,2);
5461
if (PQresultStatus(res)==PGRES_COMMAND_OK) {
5562
PQclear(res);
5663

@@ -78,10 +85,17 @@ lo_close(PGconn *conn, int fd)
7885
intretval;
7986
intresult_len;
8087

88+
if(conn->lobjfuncs== (PGlobjfuncs*)NULL) {
89+
if(lo_initialize(conn)<0) {
90+
return-1;
91+
}
92+
}
93+
8194
argv[0].isint=1;
8295
argv[0].len=4;
8396
argv[0].u.integer=fd;
84-
res=PQfn(conn,F_LO_CLOSE,&retval,&result_len,1,argv,1);
97+
res=PQfn(conn,conn->lobjfuncs->fn_lo_close,
98+
&retval,&result_len,1,argv,1);
8599
if (PQresultStatus(res)==PGRES_COMMAND_OK) {
86100
PQclear(res);
87101
returnretval;
@@ -104,6 +118,12 @@ lo_read(PGconn *conn, int fd, char *buf, int len)
104118
PGresult*res;
105119
intresult_len;
106120

121+
if(conn->lobjfuncs== (PGlobjfuncs*)NULL) {
122+
if(lo_initialize(conn)<0) {
123+
return-1;
124+
}
125+
}
126+
107127
argv[0].isint=1;
108128
argv[0].len=4;
109129
argv[0].u.integer=fd;
@@ -112,7 +132,8 @@ lo_read(PGconn *conn, int fd, char *buf, int len)
112132
argv[1].len=4;
113133
argv[1].u.integer=len;
114134

115-
res=PQfn(conn,F_LOREAD,(int*)buf,&result_len,0,argv,2);
135+
res=PQfn(conn,conn->lobjfuncs->fn_lo_read,
136+
(int*)buf,&result_len,0,argv,2);
116137
if (PQresultStatus(res)==PGRES_COMMAND_OK) {
117138
PQclear(res);
118139
returnresult_len;
@@ -133,6 +154,12 @@ lo_write(PGconn *conn, int fd, char *buf, int len)
133154
intresult_len;
134155
intretval;
135156

157+
if(conn->lobjfuncs== (PGlobjfuncs*)NULL) {
158+
if(lo_initialize(conn)<0) {
159+
return-1;
160+
}
161+
}
162+
136163
if (len <=0)
137164
return0;
138165

@@ -144,7 +171,8 @@ lo_write(PGconn *conn, int fd, char *buf, int len)
144171
argv[1].len=len;
145172
argv[1].u.ptr= (int*)buf;
146173

147-
res=PQfn(conn,F_LOWRITE,&retval,&result_len,1,argv,2);
174+
res=PQfn(conn,conn->lobjfuncs->fn_lo_write,
175+
&retval,&result_len,1,argv,2);
148176
if (PQresultStatus(res)==PGRES_COMMAND_OK) {
149177
PQclear(res);
150178
returnretval;
@@ -167,6 +195,12 @@ lo_lseek(PGconn *conn, int fd, int offset, int whence)
167195
intretval;
168196
intresult_len;
169197

198+
if(conn->lobjfuncs== (PGlobjfuncs*)NULL) {
199+
if(lo_initialize(conn)<0) {
200+
return-1;
201+
}
202+
}
203+
170204
argv[0].isint=1;
171205
argv[0].len=4;
172206
argv[0].u.integer=fd;
@@ -179,7 +213,8 @@ lo_lseek(PGconn *conn, int fd, int offset, int whence)
179213
argv[2].len=4;
180214
argv[2].u.integer=whence;
181215

182-
res=PQfn(conn,F_LO_LSEEK,&retval,&result_len,1,argv,3);
216+
res=PQfn(conn,conn->lobjfuncs->fn_lo_lseek,
217+
&retval,&result_len,1,argv,3);
183218
if (PQresultStatus(res)==PGRES_COMMAND_OK) {
184219
PQclear(res);
185220
returnretval;
@@ -204,10 +239,17 @@ lo_creat(PGconn *conn, int mode)
204239
intretval;
205240
intresult_len;
206241

242+
if(conn->lobjfuncs== (PGlobjfuncs*)NULL) {
243+
if(lo_initialize(conn)<0) {
244+
return-1;
245+
}
246+
}
247+
207248
argv[0].isint=1;
208249
argv[0].len=4;
209250
argv[0].u.integer=mode;
210-
res=PQfn(conn,F_LO_CREAT,&retval,&result_len,1,argv,1);
251+
res=PQfn(conn,conn->lobjfuncs->fn_lo_creat,
252+
&retval,&result_len,1,argv,1);
211253
if (PQresultStatus(res)==PGRES_COMMAND_OK) {
212254
PQclear(res);
213255
return (Oid)retval;
@@ -230,11 +272,18 @@ lo_tell(PGconn *conn, int fd)
230272
PGresult*res;
231273
intresult_len;
232274

275+
if(conn->lobjfuncs== (PGlobjfuncs*)NULL) {
276+
if(lo_initialize(conn)<0) {
277+
return-1;
278+
}
279+
}
280+
233281
argv[0].isint=1;
234282
argv[0].len=4;
235283
argv[0].u.integer=fd;
236284

237-
res=PQfn(conn,F_LO_TELL,&retval,&result_len,1,argv,1);
285+
res=PQfn(conn,conn->lobjfuncs->fn_lo_tell,
286+
&retval,&result_len,1,argv,1);
238287
if (PQresultStatus(res)==PGRES_COMMAND_OK) {
239288
PQclear(res);
240289
returnretval;
@@ -256,11 +305,18 @@ lo_unlink(PGconn *conn, Oid lobjId)
256305
intresult_len;
257306
intretval;
258307

308+
if(conn->lobjfuncs== (PGlobjfuncs*)NULL) {
309+
if(lo_initialize(conn)<0) {
310+
return-1;
311+
}
312+
}
313+
259314
argv[0].isint=1;
260315
argv[0].len=4;
261316
argv[0].u.integer=lobjId;
262317

263-
res=PQfn(conn,F_LO_UNLINK,&retval,&result_len,1,argv,1);
318+
res=PQfn(conn,conn->lobjfuncs->fn_lo_unlink,
319+
&retval,&result_len,1,argv,1);
264320
if (PQresultStatus(res)==PGRES_COMMAND_OK) {
265321
PQclear(res);
266322
returnretval;
@@ -380,3 +436,157 @@ lo_export(PGconn *conn, Oid lobjId, char *filename)
380436

381437
return1;
382438
}
439+
440+
441+
/* ----------------
442+
* lo_initialize
443+
*
444+
* Initialize the large object interface for an existing connection.
445+
* We ask the backend about the functions OID's in pg_proc for all
446+
* functions that are required for large object operations.
447+
* ----------------
448+
*/
449+
staticintlo_initialize(PGconn*conn)
450+
{
451+
PGresult*res;
452+
PGlobjfuncs*lobjfuncs;
453+
intn;
454+
char*fname;
455+
Oidfoid;
456+
457+
/* ----------------
458+
* Allocate the structure to hold the functions OID's
459+
* ----------------
460+
*/
461+
lobjfuncs= (PGlobjfuncs*)malloc(sizeof(PGlobjfuncs));
462+
if (lobjfuncs== (PGlobjfuncs*)NULL) {
463+
strcpy(conn->errorMessage,
464+
"FATAL: malloc() failed in lo_initialize()\n");
465+
return-1;
466+
}
467+
memset((char*)lobjfuncs,0,sizeof(PGlobjfuncs));
468+
469+
/* ----------------
470+
* Execute the query to get all the functions at once
471+
* ----------------
472+
*/
473+
res=PQexec(conn,"select proname, oid from pg_proc\
474+
where proname = 'lo_open'\
475+
or proname = 'lo_close'\
476+
or proname = 'lo_creat'\
477+
or proname = 'lo_unlink'\
478+
or proname = 'lo_lseek'\
479+
or proname = 'lo_tell'\
480+
or proname = 'LOread'\
481+
or proname = 'LOwrite'");
482+
if (res== (PGresult*)NULL) {
483+
free(lobjfuncs);
484+
return-1;
485+
}
486+
487+
if (res->resultStatus!=PGRES_TUPLES_OK) {
488+
free(lobjfuncs);
489+
PQclear(res);
490+
strcpy(conn->errorMessage,
491+
"ERROR: SELECT didn't return data in lo_initialize()\n");
492+
return-1;
493+
}
494+
495+
/* ----------------
496+
* Examine the result and put the OID's into the struct
497+
* ----------------
498+
*/
499+
for(n=0;n<PQntuples(res);n++) {
500+
fname=PQgetvalue(res,n,0);
501+
foid= (Oid)atoi(PQgetvalue(res,n,1));
502+
if(!strcmp(fname,"lo_open")) {
503+
lobjfuncs->fn_lo_open=foid;
504+
}else
505+
if(!strcmp(fname,"lo_close")) {
506+
lobjfuncs->fn_lo_close=foid;
507+
}else
508+
if(!strcmp(fname,"lo_creat")) {
509+
lobjfuncs->fn_lo_creat=foid;
510+
}else
511+
if(!strcmp(fname,"lo_unlink")) {
512+
lobjfuncs->fn_lo_unlink=foid;
513+
}else
514+
if(!strcmp(fname,"lo_lseek")) {
515+
lobjfuncs->fn_lo_lseek=foid;
516+
}else
517+
if(!strcmp(fname,"lo_tell")) {
518+
lobjfuncs->fn_lo_tell=foid;
519+
}else
520+
if(!strcmp(fname,"LOread")) {
521+
lobjfuncs->fn_lo_read=foid;
522+
}else
523+
if(!strcmp(fname,"LOwrite")) {
524+
lobjfuncs->fn_lo_write=foid;
525+
}
526+
}
527+
528+
PQclear(res);
529+
530+
/* ----------------
531+
* Finally check that we really got all large object
532+
* interface functions.
533+
* ----------------
534+
*/
535+
if(lobjfuncs->fn_lo_open==0) {
536+
strcpy(conn->errorMessage,
537+
"ERROR: Cannot determine OID for function lo_open\n");
538+
free(lobjfuncs);
539+
return-1;
540+
}
541+
if(lobjfuncs->fn_lo_close==0) {
542+
strcpy(conn->errorMessage,
543+
"ERROR: Cannot determine OID for function lo_close\n");
544+
free(lobjfuncs);
545+
return-1;
546+
}
547+
if(lobjfuncs->fn_lo_creat==0) {
548+
strcpy(conn->errorMessage,
549+
"ERROR: Cannot determine OID for function lo_creat\n");
550+
free(lobjfuncs);
551+
return-1;
552+
}
553+
if(lobjfuncs->fn_lo_unlink==0) {
554+
strcpy(conn->errorMessage,
555+
"ERROR: Cannot determine OID for function lo_unlink\n");
556+
free(lobjfuncs);
557+
return-1;
558+
}
559+
if(lobjfuncs->fn_lo_lseek==0) {
560+
strcpy(conn->errorMessage,
561+
"ERROR: Cannot determine OID for function lo_lseek\n");
562+
free(lobjfuncs);
563+
return-1;
564+
}
565+
if(lobjfuncs->fn_lo_tell==0) {
566+
strcpy(conn->errorMessage,
567+
"ERROR: Cannot determine OID for function lo_tell\n");
568+
free(lobjfuncs);
569+
return-1;
570+
}
571+
if(lobjfuncs->fn_lo_read==0) {
572+
strcpy(conn->errorMessage,
573+
"ERROR: Cannot determine OID for function LOread\n");
574+
free(lobjfuncs);
575+
return-1;
576+
}
577+
if(lobjfuncs->fn_lo_write==0) {
578+
strcpy(conn->errorMessage,
579+
"ERROR: Cannot determine OID for function LOwrite\n");
580+
free(lobjfuncs);
581+
return-1;
582+
}
583+
584+
/* ----------------
585+
* Put the structure into the connection control
586+
* ----------------
587+
*/
588+
conn->lobjfuncs=lobjfuncs;
589+
return0;
590+
}
591+
592+

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp