postgres 0.7.1 → 0.7.9.2007.12.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,65 @@
1
+ #define BOOLOID 16
2
+ #define BYTEAOID 17
3
+ #define CHAROID 18
4
+ #define NAMEOID 19
5
+ #define INT8OID 20
6
+ #define INT2OID 21
7
+ #define INT2VECTOROID 22
8
+ #define INT4OID 23
9
+ #define REGPROCOID 24
10
+ #define TEXTOID 25
11
+ #define OIDOID 26
12
+ #define TIDOID 27
13
+ #define XIDOID 28
14
+ #define CIDOID 29
15
+ #define OIDVECTOROID 30
16
+ #define PG_TYPE_RELTYPE_OID 71
17
+ #define PG_ATTRIBUTE_RELTYPE_OID 75
18
+ #define PG_PROC_RELTYPE_OID 81
19
+ #define PG_CLASS_RELTYPE_OID 83
20
+ #define POINTOID 600
21
+ #define LSEGOID 601
22
+ #define PATHOID 602
23
+ #define BOXOID 603
24
+ #define POLYGONOID 604
25
+ #define LINEOID 628
26
+ #define FLOAT4OID 700
27
+ #define FLOAT8OID 701
28
+ #define ABSTIMEOID 702
29
+ #define RELTIMEOID 703
30
+ #define TINTERVALOID 704
31
+ #define UNKNOWNOID 705
32
+ #define CIRCLEOID 718
33
+ #define CASHOID 790
34
+ #define MACADDROID 829
35
+ #define INETOID 869
36
+ #define CIDROID 650
37
+ #define INT4ARRAYOID 1007
38
+ #define ACLITEMOID 1033
39
+ #define BPCHAROID 1042
40
+ #define VARCHAROID 1043
41
+ #define DATEOID 1082
42
+ #define TIMEOID 1083
43
+ #define TIMESTAMPOID 1114
44
+ #define TIMESTAMPTZOID 1184
45
+ #define INTERVALOID 1186
46
+ #define TIMETZOID 1266
47
+ #define BITOID 1560
48
+ #define VARBITOID 1562
49
+ #define NUMERICOID 1700
50
+ #define REFCURSOROID 1790
51
+ #define REGPROCEDUREOID 2202
52
+ #define REGOPEROID 2203
53
+ #define REGOPERATOROID 2204
54
+ #define REGCLASSOID 2205
55
+ #define REGTYPEOID 2206
56
+ #define RECORDOID 2249
57
+ #define CSTRINGOID 2275
58
+ #define ANYOID 2276
59
+ #define ANYARRAYOID 2277
60
+ #define VOIDOID 2278
61
+ #define TRIGGEROID 2279
62
+ #define LANGUAGE_HANDLEROID 2280
63
+ #define INTERNALOID 2281
64
+ #define OPAQUEOID 2282
65
+ #define ANYELEMENTOID 2283
data/ext/compat.c ADDED
@@ -0,0 +1,461 @@
1
+ /************************************************
2
+
3
+ compat.c -
4
+
5
+ Author: matz
6
+ created at: Tue May 13 20:07:35 JST 1997
7
+
8
+ Author: ematsu
9
+ modified at: Wed Jan 20 16:41:51 1999
10
+
11
+ $Author: jdavis $
12
+ $Date: 2007-12-04 14:25:44 -0800 (Tue, 04 Dec 2007) $
13
+ ************************************************/
14
+
15
+ #include "compat.h"
16
+
17
+
18
+ #ifndef HAVE_PQESCAPESTRINGCONN
19
+ size_t
20
+ PQescapeStringConn(PGconn *conn, char *to, const char *from,
21
+ size_t length, int *error)
22
+ {
23
+ return PQescapeString(to,from,length);
24
+ }
25
+
26
+ unsigned char *
27
+ PQescapeByteaConn(PGconn *conn, const unsigned char *from,
28
+ size_t from_length, size_t *to_length)
29
+ {
30
+ return PQescapeBytea(from, from_length, to_length);
31
+ }
32
+ #endif /* HAVE_PQESCAPESTRINGCONN */
33
+
34
+ #ifndef HAVE_PQPREPARE
35
+ PGresult *
36
+ PQprepare(PGconn *conn, const char *stmtName, const char *query,
37
+ int nParams, const Oid *paramTypes)
38
+ {
39
+ rb_raise(rb_eStandardError, "PQprepare not supported by this client version.");
40
+ }
41
+ #endif /* HAVE_PQPREPARE */
42
+
43
+ #ifndef HAVE_PQCONNECTIONUSEDPASSWORD
44
+ int
45
+ PQconnectionUsedPassword(PGconn *conn)
46
+ {
47
+ rb_raise(rb_eStandardError,
48
+ "PQconnectionUsedPassword not supported by this client version.");
49
+ }
50
+ #endif /* HAVE_PQCONNECTIONUSEDPASSWORD */
51
+
52
+ #ifndef HAVE_PQISTHREADSAFE
53
+ int
54
+ PQisthreadsafe()
55
+ {
56
+ return Qfalse;
57
+ }
58
+ #endif /* HAVE_PQISTHREADSAFE */
59
+
60
+ #ifndef HAVE_LO_TRUNCATE
61
+ int
62
+ lo_truncate(PGconn *conn, int fd, size_t len)
63
+ {
64
+ rb_raise(rb_eStandardError, "lo_truncate not supported by this client version.");
65
+ }
66
+ #endif /* HAVE_LO_TRUNCATE */
67
+
68
+ #ifndef HAVE_LO_CREATE
69
+ Oid
70
+ lo_create(PGconn *conn, Oid lobjId)
71
+ {
72
+ rb_raise(rb_eStandardError, "lo_create not supported by this client version.");
73
+ }
74
+ #endif /* HAVE_LO_CREATE */
75
+
76
+ #ifndef HAVE_PQNPARAMS
77
+ int
78
+ PQnparams(const PGresult *res)
79
+ {
80
+ rb_raise(rb_eStandardError, "PQnparams not supported by this client version.");
81
+ }
82
+ #endif /* HAVE_PQNPARAMS */
83
+
84
+ #ifndef HAVE_PQPARAMTYPE
85
+ Oid
86
+ PQparamtype(const PGresult *res, int param_number)
87
+ {
88
+ rb_raise(rb_eStandardError, "PQparamtype not supported by this client version.");
89
+ }
90
+ #endif /* HAVE_PQPARAMTYPE */
91
+
92
+ #ifndef HAVE_PQSERVERVERSION
93
+ int
94
+ PQserverVersion(const PGconn* conn)
95
+ {
96
+ rb_raise(rb_eStandardError, "PQserverVersion not supported by this client version.");
97
+ }
98
+ #endif /* HAVE_PQSERVERVERSION */
99
+
100
+ #ifndef HAVE_PQSENDDESCRIBEPREPARED
101
+ int
102
+ PQsendDescribePrepared(PGconn *conn, const char *stmtName)
103
+ {
104
+ rb_raise(rb_eStandardError, "PQsendDescribePrepared not supported by this client version.");
105
+ }
106
+ #endif /* HAVE_PQSENDDESCRIBEPREPARED */
107
+
108
+ #ifndef HAVE_PQSENDDESCRIBEPORTAL
109
+ int
110
+ PQsendDescribePortal(PGconn *conn, const char *portalName)
111
+ {
112
+ rb_raise(rb_eStandardError, "PQsendDescribePortal not supported by this client version.");
113
+ }
114
+ #endif /* HAVE_PQSENDDESCRIBEPORTAL */
115
+
116
+ #ifndef HAVE_PQENCRYPTPASSWORD
117
+ char *
118
+ PQencryptPassword(const char *passwd, const char *user)
119
+ {
120
+ rb_raise(rb_eStandardError, "PQencryptPassword not supported by this client version.");
121
+ }
122
+ #endif /* HAVE_PQENCRYPTPASSWORD */
123
+
124
+ #ifndef HAVE_PQEXECPARAMS
125
+ PGresult *
126
+ PQexecParams(PGconn *conn, const char *command, int nParams,
127
+ const Oid *paramTypes, const char * const * paramValues, const int *paramLengths,
128
+ const int *paramFormats, int resultFormat)
129
+ {
130
+ rb_raise(rb_eStandardError, "PQexecParams not supported by this client version.");
131
+ }
132
+
133
+ #define BIND_PARAM_PATTERN "\\$(\\d+)"
134
+ #include <ruby.h>
135
+ #include <re.h>
136
+ PGresult *
137
+ PQexecParams_compat(PGconn *conn, VALUE command, VALUE values)
138
+ {
139
+ VALUE bind_param_re = rb_reg_new(BIND_PARAM_PATTERN, 7, 0);
140
+ VALUE result = rb_str_buf_new(RSTRING(command)->len);
141
+ char* ptr = RSTRING(command)->ptr;
142
+ int scan = 0;
143
+ while ((scan = rb_reg_search(bind_param_re, command, scan, 0)) > 0) {
144
+ VALUE match = rb_backref_get();
145
+ int pos = BindParamNumber(match);
146
+ if (pos < RARRAY(values)->len) {
147
+ rb_str_buf_cat(result, ptr, scan - (ptr - RSTRING(command)->ptr));
148
+ ptr = RSTRING(command)->ptr + scan;
149
+ rb_str_buf_append(result, RARRAY(values)->ptr[pos]);
150
+ }
151
+ scan += RSTRING(rb_reg_nth_match(0, match))->len;
152
+ ptr += RSTRING(rb_reg_nth_match(0, match))->len;
153
+ }
154
+ rb_str_buf_cat(result, ptr, RSTRING(command)->len - (ptr - RSTRING(command)->ptr));
155
+
156
+ return PQexec(conn, StringValuePtr(result));
157
+ }
158
+ #endif /* HAVE_PQEXECPARAMS */
159
+
160
+
161
+ /**************************************************************************
162
+
163
+ IF ANY CODE IS COPIED FROM POSTGRESQL, PLACE IT AFTER THIS COMMENT.
164
+ THE BSD LICENSE REQUIRES THAT YOU MAINTAIN THIS COPYRIGHT NOTICE.
165
+
166
+ ***************************************************************************
167
+
168
+ Portions of code after this point were copied from the PostgreSQL source
169
+ distribution, available at http://www.postgresql.org
170
+
171
+ ***************************************************************************
172
+
173
+ Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
174
+
175
+ Portions Copyright (c) 1994, The Regents of the University of California
176
+
177
+ Permission to use, copy, modify, and distribute this software and its
178
+ documentation for any purpose, without fee, and without a written agreement
179
+ is hereby granted, provided that the above copyright notice and this
180
+ paragraph and the following two paragraphs appear in all copies.
181
+
182
+ IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
183
+ DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING
184
+ LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
185
+ DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE
186
+ POSSIBILITY OF SUCH DAMAGE.
187
+
188
+ THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
189
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
190
+ AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
191
+ ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO
192
+ PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
193
+
194
+ **************************************************************************/
195
+
196
+ #ifndef HAVE_PQSETCLIENTENCODING
197
+
198
+ int
199
+ PQsetClientEncoding(PGconn *conn, const char *encoding)
200
+ {
201
+ char qbuf[128];
202
+ static const char query[] = "set client_encoding to '%s'";
203
+ PGresult *res;
204
+ int status;
205
+
206
+ if (!conn || conn->status != CONNECTION_OK)
207
+ return -1;
208
+
209
+ if (!encoding)
210
+ return -1;
211
+
212
+ /* check query buffer overflow */
213
+ if (sizeof(qbuf) < (sizeof(query) + strlen(encoding)))
214
+ return -1;
215
+
216
+ /* ok, now send a query */
217
+ sprintf(qbuf, query, encoding);
218
+ res = PQexec(conn, qbuf);
219
+
220
+ if (res == NULL)
221
+ return -1;
222
+ if (res->resultStatus != PGRES_COMMAND_OK)
223
+ status = -1;
224
+ else
225
+ {
226
+ /*
227
+ * In protocol 2 we have to assume the setting will stick, and adjust
228
+ * our state immediately. In protocol 3 and up we can rely on the
229
+ * backend to report the parameter value, and we'll change state at
230
+ * that time.
231
+ */
232
+ if (PG_PROTOCOL_MAJOR(conn->pversion) < 3)
233
+ pqSaveParameterStatus(conn, "client_encoding", encoding);
234
+ status = 0; /* everything is ok */
235
+ }
236
+ PQclear(res);
237
+ return status;
238
+ }
239
+ #endif /* HAVE_PQSETCLIENTENCODING */
240
+
241
+ #ifndef HAVE_PQESCAPESTRING
242
+ /*
243
+ * Escaping arbitrary strings to get valid SQL literal strings.
244
+ *
245
+ * Replaces "\\" with "\\\\" and "'" with "''".
246
+ *
247
+ * length is the length of the source string. (Note: if a terminating NUL
248
+ * is encountered sooner, PQescapeString stops short of "length"; the behavior
249
+ * is thus rather like strncpy.)
250
+ *
251
+ * For safety the buffer at "to" must be at least 2*length + 1 bytes long.
252
+ * A terminating NUL character is added to the output string, whether the
253
+ * input is NUL-terminated or not.
254
+ *
255
+ * Returns the actual length of the output (not counting the terminating NUL).
256
+ */
257
+ size_t
258
+ PQescapeString(char *to, const char *from, size_t length)
259
+ {
260
+ const char *source = from;
261
+ char *target = to;
262
+ size_t remaining = length;
263
+
264
+ while (remaining > 0 && *source != '\0')
265
+ {
266
+ switch (*source)
267
+ {
268
+ case '\\':
269
+ *target++ = '\\';
270
+ *target++ = '\\';
271
+ break;
272
+
273
+ case '\'':
274
+ *target++ = '\'';
275
+ *target++ = '\'';
276
+ break;
277
+
278
+ default:
279
+ *target++ = *source;
280
+ break;
281
+ }
282
+ source++;
283
+ remaining--;
284
+ }
285
+
286
+ /* Write the terminating NUL character. */
287
+ *target = '\0';
288
+
289
+ return target - to;
290
+ }
291
+
292
+ /*
293
+ * PQescapeBytea - converts from binary string to the
294
+ * minimal encoding necessary to include the string in an SQL
295
+ * INSERT statement with a bytea type column as the target.
296
+ *
297
+ * The following transformations are applied
298
+ * '\0' == ASCII 0 == \\000
299
+ * '\'' == ASCII 39 == \'
300
+ * '\\' == ASCII 92 == \\\\
301
+ * anything < 0x20, or > 0x7e ---> \\ooo
302
+ * (where ooo is an octal expression)
303
+ */
304
+ unsigned char *
305
+ PQescapeBytea(const unsigned char *bintext, size_t binlen, size_t *bytealen)
306
+ {
307
+ const unsigned char *vp;
308
+ unsigned char *rp;
309
+ unsigned char *result;
310
+ size_t i;
311
+ size_t len;
312
+
313
+ /*
314
+ * empty string has 1 char ('\0')
315
+ */
316
+ len = 1;
317
+
318
+ vp = bintext;
319
+ for (i = binlen; i > 0; i--, vp++)
320
+ {
321
+ if (*vp < 0x20 || *vp > 0x7e)
322
+ len += 5; /* '5' is for '\\ooo' */
323
+ else if (*vp == '\'')
324
+ len += 2;
325
+ else if (*vp == '\\')
326
+ len += 4;
327
+ else
328
+ len++;
329
+ }
330
+
331
+ rp = result = (unsigned char *) malloc(len);
332
+ if (rp == NULL)
333
+ return NULL;
334
+
335
+ vp = bintext;
336
+ *bytealen = len;
337
+
338
+ for (i = binlen; i > 0; i--, vp++)
339
+ {
340
+ if (*vp < 0x20 || *vp > 0x7e)
341
+ {
342
+ (void) sprintf(rp, "\\\\%03o", *vp);
343
+ rp += 5;
344
+ }
345
+ else if (*vp == '\'')
346
+ {
347
+ rp[0] = '\\';
348
+ rp[1] = '\'';
349
+ rp += 2;
350
+ }
351
+ else if (*vp == '\\')
352
+ {
353
+ rp[0] = '\\';
354
+ rp[1] = '\\';
355
+ rp[2] = '\\';
356
+ rp[3] = '\\';
357
+ rp += 4;
358
+ }
359
+ else
360
+ *rp++ = *vp;
361
+ }
362
+ *rp = '\0';
363
+
364
+ return result;
365
+ }
366
+
367
+ #define ISFIRSTOCTDIGIT(CH) ((CH) >= '0' && (CH) <= '3')
368
+ #define ISOCTDIGIT(CH) ((CH) >= '0' && (CH) <= '7')
369
+ #define OCTVAL(CH) ((CH) - '0')
370
+
371
+ /*
372
+ * PQunescapeBytea - converts the null terminated string representation
373
+ * of a bytea, strtext, into binary, filling a buffer. It returns a
374
+ * pointer to the buffer (or NULL on error), and the size of the
375
+ * buffer in retbuflen. The pointer may subsequently be used as an
376
+ * argument to the function free(3). It is the reverse of PQescapeBytea.
377
+ *
378
+ * The following transformations are made:
379
+ * \\ == ASCII 92 == \
380
+ * \ooo == a byte whose value = ooo (ooo is an octal number)
381
+ * \x == x (x is any character not matched by the above transformations)
382
+ */
383
+ unsigned char *
384
+ PQunescapeBytea(const unsigned char *strtext, size_t *retbuflen)
385
+ {
386
+ size_t strtextlen,
387
+ buflen;
388
+ unsigned char *buffer,
389
+ *tmpbuf;
390
+ size_t i,
391
+ j;
392
+
393
+ if (strtext == NULL)
394
+ return NULL;
395
+
396
+ strtextlen = strlen(strtext);
397
+
398
+ /*
399
+ * Length of input is max length of output, but add one to avoid
400
+ * unportable malloc(0) if input is zero-length.
401
+ */
402
+ buffer = (unsigned char *) malloc(strtextlen + 1);
403
+ if (buffer == NULL)
404
+ return NULL;
405
+
406
+ for (i = j = 0; i < strtextlen;)
407
+ {
408
+ switch (strtext[i])
409
+ {
410
+ case '\\':
411
+ i++;
412
+ if (strtext[i] == '\\')
413
+ buffer[j++] = strtext[i++];
414
+ else
415
+ {
416
+ if ((ISFIRSTOCTDIGIT(strtext[i])) &&
417
+ (ISOCTDIGIT(strtext[i + 1])) &&
418
+ (ISOCTDIGIT(strtext[i + 2])))
419
+ {
420
+ int byte;
421
+
422
+ byte = OCTVAL(strtext[i++]);
423
+ byte = (byte << 3) + OCTVAL(strtext[i++]);
424
+ byte = (byte << 3) + OCTVAL(strtext[i++]);
425
+ buffer[j++] = byte;
426
+ }
427
+ }
428
+
429
+ /*
430
+ * Note: if we see '\' followed by something that isn't a
431
+ * recognized escape sequence, we loop around having done
432
+ * nothing except advance i. Therefore the something will
433
+ * be emitted as ordinary data on the next cycle. Corner
434
+ * case: '\' at end of string will just be discarded.
435
+ */
436
+ break;
437
+
438
+ default:
439
+ buffer[j++] = strtext[i++];
440
+ break;
441
+ }
442
+ }
443
+ buflen = j; /* buflen is the length of the dequoted
444
+ * data */
445
+
446
+ /* Shrink the buffer to be no larger than necessary */
447
+ /* +1 avoids unportable behavior when buflen==0 */
448
+ tmpbuf = realloc(buffer, buflen + 1);
449
+
450
+ /* It would only be a very brain-dead realloc that could fail, but... */
451
+ if (!tmpbuf)
452
+ {
453
+ free(buffer);
454
+ return NULL;
455
+ }
456
+
457
+ *retbuflen = buflen;
458
+ return tmpbuf;
459
+ }
460
+ #endif
461
+
data/ext/compat.h ADDED
@@ -0,0 +1,106 @@
1
+
2
+ #ifndef __compat_h
3
+ #define __compat_h
4
+
5
+ #include <stdlib.h>
6
+
7
+ #include "ruby.h"
8
+ #include "rubyio.h"
9
+ #include "st.h"
10
+ #include "libpq-fe.h"
11
+ #include "libpq/libpq-fs.h" /* large-object interface */
12
+
13
+ #if RUBY_VERSION_CODE < 180
14
+ #define rb_check_string_type(x) rb_check_convert_type(x, T_STRING, "String", "to_str")
15
+ #endif /* RUBY_VERSION_CODE < 180 */
16
+
17
+ #ifndef StringValuePtr
18
+ #define StringValuePtr(x) STR2CSTR(x)
19
+ #endif /* StringValuePtr */
20
+
21
+ #ifndef HAVE_PG_ENCODING_TO_CHAR
22
+ #define pg_encoding_to_char(x) "SQL_ASCII"
23
+ #endif /* HAVE_PG_ENCODING_TO_CHAR */
24
+
25
+ #ifndef PG_DIAG_INTERNAL_POSITION
26
+ #define PG_DIAG_INTERNAL_POSITION 'p'
27
+ #endif /* PG_DIAG_INTERNAL_POSITION */
28
+
29
+ #ifndef PG_DIAG_INTERNAL_QUERY
30
+ #define PG_DIAG_INTERNAL_QUERY 'q'
31
+ #endif /* PG_DIAG_INTERNAL_QUERY */
32
+
33
+ #ifndef HAVE_PQFREEMEM
34
+ #define PQfreemem(ptr) free(ptr)
35
+ #endif /* HAVE_PQFREEMEM */
36
+
37
+ #ifndef HAVE_PQSETCLIENTENCODING
38
+ int PQsetClientEncoding(PGconn *conn, const char *encoding)
39
+ #endif /* HAVE_PQSETCLIENTENCODING */
40
+
41
+ #ifndef HAVE_PQESCAPESTRING
42
+ size_t PQescapeString(char *to, const char *from, size_t length);
43
+ unsigned char * PQescapeBytea(const unsigned char *bintext, size_t binlen, size_t *bytealen);
44
+ unsigned char * PQunescapeBytea(const unsigned char *strtext, size_t *retbuflen);
45
+ #endif /* HAVE_PQESCAPESTRING */
46
+
47
+ #ifndef HAVE_PQESCAPESTRINGCONN
48
+ size_t PQescapeStringConn(PGconn *conn, char *to, const char *from,
49
+ size_t length, int *error);
50
+ unsigned char *PQescapeByteaConn(PGconn *conn, const unsigned char *from,
51
+ size_t from_length, size_t *to_length);
52
+ #endif /* HAVE_PQESCAPESTRINGCONN */
53
+
54
+ #ifndef HAVE_PQPREPARE
55
+ PGresult *PQprepare(PGconn *conn, const char *stmtName, const char *query,
56
+ int nParams, const Oid *paramTypes);
57
+ #endif /* HAVE_PQPREPARE */
58
+
59
+ #ifndef HAVE_PQCONNECTIONUSEDPASSWORD
60
+ int PQconnectionUsedPassword(PGconn *conn);
61
+ #endif /* HAVE_PQCONNECTIONUSEDPASSWORD */
62
+
63
+ #ifndef HAVE_PQISTHREADSAFE
64
+ int PQisthreadsafe(void);
65
+ #endif /* HAVE_PQISTHREADSAFE */
66
+
67
+ #ifndef HAVE_LO_TRUNCATE
68
+ int lo_truncate(PGconn *conn, int fd, size_t len);
69
+ #endif /* HAVE_LO_TRUNCATE */
70
+
71
+ #ifndef HAVE_LO_CREATE
72
+ Oid lo_create(PGconn *conn, Oid lobjId);
73
+ #endif /* HAVE_LO_CREATE */
74
+
75
+ #ifndef HAVE_PQNPARAMS
76
+ int PQnparams(const PGresult *res);
77
+ #endif /* HAVE_PQNPARAMS */
78
+
79
+ #ifndef HAVE_PQPARAMTYPE
80
+ Oid PQparamtype(const PGresult *res, int param_number);
81
+ #endif /* HAVE_PQPARAMTYPE */
82
+
83
+ #ifndef HAVE_PQSERVERVERSION
84
+ int PQserverVersion(const PGconn* conn);
85
+ #endif /* HAVE_PQSERVERVERSION */
86
+
87
+ #ifndef HAVE_PQEXECPARAMS
88
+ PGresult *PQexecParams(PGconn *conn, const char *command, int nParams,
89
+ const Oid *paramTypes, const char * const * paramValues, const int *paramLengths,
90
+ const int *paramFormats, int resultFormat);
91
+ PGresult *PQexecParams_compat(PGconn *conn, VALUE command, VALUE values);
92
+ #endif /* HAVE_PQEXECPARAMS */
93
+
94
+ #ifndef HAVE_PQSENDDESCRIBEPREPARED
95
+ int PQsendDescribePrepared(PGconn *conn, const char *stmtName);
96
+ #endif /* HAVE_PQSENDDESCRIBEPREPARED */
97
+
98
+ #ifndef HAVE_PQSENDDESCRIBEPORTAL
99
+ int PQsendDescribePortal(PGconn *conn, const char *portalName);
100
+ #endif /* HAVE_PQSENDDESCRIBEPORTAL */
101
+
102
+ #ifndef HAVE_PQENCRYPTPASSWORD
103
+ char *PQencryptPassword(const char *passwd, const char *user);
104
+ #endif /* HAVE_PQENCRYPTPASSWORD */
105
+
106
+ #endif /* __compat_h */
data/ext/extconf.rb ADDED
@@ -0,0 +1,48 @@
1
+ if RUBY_VERSION < '1.3'
2
+ puts 'This library is for ruby-1.3 or higher.'
3
+ exit 1
4
+ end
5
+
6
+ require 'mkmf'
7
+
8
+ def config_value(type)
9
+ ENV["POSTGRES_#{type.upcase}"] || pg_config(type)
10
+ end
11
+
12
+ def pg_config(type)
13
+ IO.popen("pg_config --#{type}dir").readline.chomp rescue nil
14
+ end
15
+
16
+ def have_build_env
17
+ have_library('pq') && have_header('libpq-fe.h') && have_header('libpq/libpq-fs.h')
18
+ end
19
+
20
+ dir_config('pgsql', config_value('include'), config_value('lib'))
21
+
22
+ desired_functions = %w(
23
+ PQsetClientEncoding
24
+ PQfreemem
25
+ PQescapeStringConn
26
+ PQprepare
27
+ PQescapeString
28
+ PQexecParams
29
+ PQconnectionUsedPassword
30
+ PQisthreadsafe
31
+ PQnparams
32
+ PQparamtype
33
+ PQsendDescribePrepared
34
+ PQsendDescribePortal
35
+ PQencryptPassword
36
+ lo_create
37
+ lo_truncate
38
+ pg_encoding_to_char
39
+ )
40
+
41
+ if have_build_env
42
+ desired_functions.each(&method(:have_func))
43
+ $OBJS = ['pg.o','compat.o']
44
+ $CFLAGS << ' -Wall -Wmissing-prototypes'
45
+ create_makefile("pg")
46
+ else
47
+ puts 'Could not find PostgreSQL build environment (libraries & headers): Makefile not created'
48
+ end