e01828cc8e369d0d2c15b238aaf606fa259bc47d
[clsql.git] / db-postgresql / postgresql-api.lisp
1 ;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*-
2 ;;;; *************************************************************************
3 ;;;; FILE IDENTIFICATION
4 ;;;;
5 ;;;; Name:          postgresql.cl
6 ;;;; Purpose:       Low-level PostgreSQL interface using UFFI
7 ;;;; Programmers:   Kevin M. Rosenberg based on 
8 ;;;;                Original code by Pierre R. Mai 
9 ;;;; Date Started:  Feb 2002
10 ;;;;
11 ;;;; $Id$
12 ;;;;
13 ;;;; This file, part of CLSQL, is Copyright (c) 2002 by Kevin M. Rosenberg
14 ;;;; and Copyright (c) 1999-2001 by Pierre R. Mai
15 ;;;;
16 ;;;; CLSQL users are granted the rights to distribute and use this software
17 ;;;; as governed by the terms of the Lisp Lesser GNU Public License
18 ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL.
19 ;;;; *************************************************************************
20
21 (in-package #:postgresql)
22
23
24 ;;;; This file implements as little of the FFI bindings to the
25 ;;;; PostgreSQL client libraries as we could get away with.
26 ;;;; Especially all the PostgreSQL-specific goodies aren't there, and
27 ;;;; we just use void pointers where we can get away with it, which
28 ;;;; thanks to the design of the PostgreSQL client libraries is pretty
29 ;;;; much everywhere, in contrast to the MySQL client libraries for
30 ;;;; example.
31
32 ;;;; Type definitions
33
34 ;;; Basic Types
35
36 (uffi:def-foreign-type pgsql-oid :unsigned-int)
37
38 (uffi:def-enum pgsql-conn-status-type 
39     (:connection-ok
40      :connection-bad))
41
42 (uffi:def-enum pgsql-exec-status-type
43     (:empty-query
44      :command-ok
45      :tuples-ok
46      :copy-out
47      :copy-in
48      :bad-response
49      :nonfatal-error
50      :fatal-error))
51
52 (uffi:def-foreign-type pgsql-conn :pointer-void)
53 (uffi:def-foreign-type pgsql-result :pointer-void)
54
55 (uffi:def-type pgsql-conn-ptr :pointer-void)
56
57 (uffi:def-enum pgsql-ftype
58     ((:bytea 17)
59      (:int2 21)
60      (:int4 23)
61      (:int8 20)
62      (:float4 700)
63      (:float8 701)))
64   
65 ;;(declaim (inline PQsetdbLogin)) ;; causes compile error in LW 4.2.0
66 (uffi:def-function ("PQsetdbLogin" PQsetdbLogin)
67   ((pghost :cstring)
68    (pgport :cstring)
69    (pgoptions :cstring)
70    (pgtty :cstring)
71    (dbName :cstring)
72    (login :cstring)
73    (pwd :cstring))
74   :module "postgresql"
75   :returning pgsql-conn)
76
77 (declaim (inline PQfinish))
78 (uffi:def-function ("PQfinish" PQfinish)
79   ((conn pgsql-conn))
80   :module "postgresql"
81   :returning :void)
82
83 (declaim (inline PQstatus))
84 (uffi:def-function ("PQstatus" PQstatus)
85   ((conn pgsql-conn))
86   :module "postgresql"
87   :returning pgsql-conn-status-type)
88
89 (declaim (inline PQerrorMessage))
90 (uffi:def-function ("PQerrorMessage" PQerrorMessage)
91   ((conn pgsql-conn))
92   :module "postgresql"
93   :returning :cstring)
94
95 (declaim (inline PQexec))
96 (uffi:def-function ("PQexec" PQexec)
97   ((conn pgsql-conn)
98    (query :cstring))
99   :module "postgresql"
100   :returning pgsql-result)
101
102 (declaim (inline PQresultStatus))
103 (uffi:def-function ("PQresultStatus" PQresultStatus)
104   ((res pgsql-result))
105   :module "postgresql"
106   :returning pgsql-exec-status-type)
107
108 ; From postgres_ext.h
109
110 ; #define PG_DIAG_SEVERITY                'S'
111 ; #define PG_DIAG_SQLSTATE                'C'
112 ; #define PG_DIAG_MESSAGE_PRIMARY 'M'
113 ; #define PG_DIAG_MESSAGE_DETAIL  'D'
114 ; #define PG_DIAG_MESSAGE_HINT    'H'
115 ; #define PG_DIAG_STATEMENT_POSITION 'P'
116 ; #define PG_DIAG_INTERNAL_POSITION 'p'
117 ; #define PG_DIAG_INTERNAL_QUERY  'q'
118 ; #define PG_DIAG_CONTEXT                 'W'
119 ; #define PG_DIAG_SOURCE_FILE             'F'
120 ; #define PG_DIAG_SOURCE_LINE             'L'
121 ; #define PG_DIAG_SOURCE_FUNCTION 'R'
122 (defconstant +PG-DIAG-SEVERITY+ (char-code #\S))
123 (defconstant +PG-DIAG-SQLSTATE+ (char-code #\C))
124 (defconstant +PG-DIAG-MESSAGE-PRIMARY+ (char-code #\M))
125 (defconstant +PG-DIAG-MESSAGE-DETAIL+ (char-code #\D))
126 (defconstant +PG-DIAG-MESSAGE-HINT+ (char-code #\H))
127 (defconstant +PG-DIAG-STATEMENT-POSITION+ (char-code #\P))
128 (defconstant +PG-DIAG-INTERNAL-POSITION+ (char-code #\p))
129 (defconstant +PG-DIAG-INTERNAL-QUERY+ (char-code #\q))
130 (defconstant +PG-DIAG-CONTEXT+ (char-code #\W))
131 (defconstant +PG-DIAG-SOURCE-FILE+ (char-code #\F))
132 (defconstant +PG-DIAG-SOURCE-LINE+ (char-code #\L))
133 (defconstant +PG-DIAG-SOURCE-FUNCTION+ (char-code #\R))
134
135 ; PQresultErrorField can return diagnostic information about an error
136 (declaim (inline PQresultErrorField))
137 (uffi:def-function ("PQresultErrorField" PQresultErrorField)
138     ((res pgsql-result)
139      (field-code :int))
140   :module "postgresql"
141   :returning :cstring)
142
143 (declaim (inline PQresultErrorMessage))
144 (uffi:def-function ("PQresultErrorMessage" PQresultErrorMessage)
145   ((res pgsql-result))
146   :module "postgresql"
147   :returning :cstring)
148
149 (declaim (inline PQntuples))
150 (uffi:def-function ("PQntuples" PQntuples) 
151   ((res pgsql-result))
152   :module "postgresql"
153   :returning :int)
154
155 (declaim (inline PQnfields))
156 (uffi:def-function ("PQnfields" PQnfields)
157   ((res pgsql-result))
158   :module "postgresql"
159   :returning :int)
160
161 (declaim (inline PQfname))
162 (uffi:def-function ("PQfname" PQfname)
163   ((res pgsql-result)
164    (field-num :int))
165   :module "postgresql"
166   :returning :cstring)
167
168 (declaim (inline PQfnumber))
169 (uffi:def-function ("PQfnumber" PQfnumber)
170   ((res pgsql-result)
171   (field-name :cstring))
172   :module "postgresql"
173   :returning :int)
174
175 (declaim (inline PQftype))
176 (uffi:def-function ("PQftype" PQftype)
177   ((res pgsql-result)
178    (field-num :int))
179   :module "postgresql"
180   :returning pgsql-oid)
181
182 (declaim (inline PQfsize))
183 (uffi:def-function ("PQfsize" PQfsize)
184   ((res pgsql-result)
185    (field-num :int))
186   :module "postgresql"
187   :returning :short)
188
189 (declaim (inline PQcmdStatus))
190 (uffi:def-function ("PQcmdStatus" PQcmdStatus)
191   ((res pgsql-result))
192   :module "postgresql"
193   :returning :cstring)
194
195 (declaim (inline PQoidStatus))
196 (uffi:def-function ("PQoidStatus" PQoidStatus)
197   ((res pgsql-result))
198   :module "postgresql"
199   :returning :cstring)
200
201 (declaim (inline PQcmdTuples))
202 (uffi:def-function ("PQcmdTuples" PQcmdTuples)
203   ((res pgsql-result))
204   :module "postgresql"
205   :returning :cstring)
206
207 (declaim (inline PQgetvalue))
208 (uffi:def-function ("PQgetvalue" PQgetvalue)
209   ((res pgsql-result)
210    (tup-num :int)
211    (field-num :int))
212   :module "postgresql"
213   :returning (* :unsigned-char))
214
215 (declaim (inline PQgetlength))
216 (uffi:def-function ("PQgetlength" PQgetlength)
217   ((res pgsql-result)
218    (tup-num :int)
219    (field-num :int))
220   :module "postgresql"
221   :returning :int)
222
223 (declaim (inline PQgetisnull))
224 (uffi:def-function ("PQgetisnull" PQgetisnull)
225   ((res pgsql-result)
226    (tup-num :int)
227    (field-num :int))
228   :module "postgresql"
229   :returning :int)
230
231 (declaim (inline PQclear))
232 (uffi:def-function ("PQclear" PQclear)
233   ((res pgsql-result))
234   :module "postgresql"
235   :returning :void)
236
237 (declaim (inline PQisBusy))
238 (uffi:def-function ("PQisBusy" PQisBusy)
239   ((conn pgsql-conn))
240   :module "postgresql"
241   :returning :int)
242
243
244 ;;; Large objects support (MB)
245
246 (defconstant +INV_ARCHIVE+ 65536)         ; fe-lobj.c
247 (defconstant +INV_WRITE+   131072)
248 (defconstant +INV_READ+    262144)
249
250 (declaim (inline lo-creat))
251 (uffi:def-function ("lo_creat" lo-create)
252   ((conn pgsql-conn)
253    (mode :int))
254   :module "postgresql"
255   :returning pgsql-oid)
256
257 (declaim (inline lo-open))
258 (uffi:def-function ("lo_open" lo-open)
259   ((conn pgsql-conn)
260    (oid pgsql-oid)
261    (mode :int))
262   :module "postgresql"
263   :returning :int)
264
265 (declaim (inline lo-write))
266 (uffi:def-function ("lo_write" lo-write)
267   ((conn pgsql-conn)
268    (fd :int)
269    (data :cstring)
270    (size :int))
271   :module "postgresql"
272   :returning :int)
273
274 (declaim (inline lo-read))
275 (uffi:def-function ("lo_read" lo-read)
276   ((conn pgsql-conn)
277    (fd :int)
278    (data (* :unsigned-char))
279    (size :int))
280   :module "postgresql"
281   :returning :int)
282
283 (declaim (inline lo-lseek))
284 (uffi:def-function ("lo_lseek" lo-lseek)
285   ((conn pgsql-conn)
286    (fd :int)
287    (offset :int)
288    (whence :int))
289   :module "postgresql"
290   :returning :int)
291
292 (declaim (inline lo-close))
293 (uffi:def-function ("lo_close" lo-close)
294   ((conn pgsql-conn)
295    (fd :int))
296   :module "postgresql"
297   :returning :int)
298
299 (declaim (inline lo-unlink))
300 (uffi:def-function ("lo_unlink" lo-unlink)
301   ((conn pgsql-conn)
302    (oid pgsql-oid))
303   :module "postgresql"
304   :returning :int)