zeoslib  UNKNOWN
 All Files
ZPlainPostgreSqlDriver.pas
Go to the documentation of this file.
1 {*********************************************************}
2 { }
3 { Zeos Database Objects }
4 { Native Plain Drivers for PostgreSQL }
5 { }
6 { Originally written by Sergey Seroukhov }
7 { }
8 {*********************************************************}
9 
10 {@********************************************************}
11 { Copyright (c) 1999-2012 Zeos Development Group }
12 { }
13 { License Agreement: }
14 { }
15 { This library is distributed in the hope that it will be }
16 { useful, but WITHOUT ANY WARRANTY; without even the }
17 { implied warranty of MERCHANTABILITY or FITNESS FOR }
18 { A PARTICULAR PURPOSE. See the GNU Lesser General }
19 { Public License for more details. }
20 { }
21 { The source code of the ZEOS Libraries and packages are }
22 { distributed under the Library GNU General Public }
23 { License (see the file COPYING / COPYING.ZEOS) }
24 { with the following modification: }
25 { As a special exception, the copyright holders of this }
26 { library give you permission to link this library with }
27 { independent modules to produce an executable, }
28 { regardless of the license terms of these independent }
29 { modules, and to copy and distribute the resulting }
30 { executable under terms of your choice, provided that }
31 { you also meet, for each linked independent module, }
32 { the terms and conditions of the license of that module. }
33 { An independent module is a module which is not derived }
34 { from or based on this library. If you modify this }
35 { library, you may extend this exception to your version }
36 { of the library, but you are not obligated to do so. }
37 { If you do not wish to do so, delete this exception }
38 { statement from your version. }
39 { }
40 { }
41 { The project web site is located on: }
42 { http://zeos.firmos.at (FORUM) }
43 { http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}
44 { svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN) }
45 { }
46 { http://www.sourceforge.net/projects/zeoslib. }
47 { }
48 { }
49 { Zeos Development Group. }
50 {********************************************************@}
51 
52 unit ZPlainPostgreSqlDriver;
53 
54 interface
55 
56 {$I ZPlain.inc}
57 
58 uses ZClasses, ZCompatibility, ZPlainDriver;
59 
60 const
61  WINDOWS_DLL_LOCATION = 'libpq.dll';
62  WINDOWS_DLL7_LOCATION = 'libpq74.dll';
63  WINDOWS_DLL8_LOCATION = 'libpq81.dll';
64  LINUX_DLL_LOCATION = 'libpq'+SharedSuffix;
65  LINUX_DLL8_LOCATION = 'libpq'+SharedSuffix+'.4';
66  LINUX_DLL82_LOCATION = 'libpq'+SharedSuffix+'.5';
67 
68 { Type Lengths }
69  NAMEDATALEN = 32;
70 
71 { OIDNAMELEN should be set to NAMEDATALEN + sizeof(Oid) }
72  OIDNAMELEN = 36;
73  InvalidOid = 0;
74 
75  INV_WRITE = $00020000;
76  INV_READ = $00040000;
77 
78  BLOB_SEEK_SET = 0;
79  BLOB_SEEK_CUR = 1;
80  BLOB_SEEK_END = 2;
81 
82 type
83 
84 { Application-visible enum types }
85  TZPostgreSQLConnectStatusType = (
86  CONNECTION_OK,
87  CONNECTION_BAD
88  );
89 
90  TZPostgreSQLFieldCode=( // FirmOS
91  PG_DIAG_SEVERITY=ord('S'),
92  PG_DIAG_SQLSTATE=ord('C'),
93  PG_DIAG_MESSAGE_PRIMARY=ord('M'),
94  PG_DIAG_MESSAGE_DETAIL=ord('D'),
95  PG_DIAG_MESSAGE_HINT=ord('H'),
96  PG_DIAG_STATEMENT_POSITION=ord('P'),
97  PG_DIAG_INTERNAL_POSITION=ord('p'),
98  PG_DIAG_INTERNAL_QUERY=ord('q'),
99  PG_DIAG_CONTEXT=ord('W'),
100  PG_DIAG_SOURCE_FILE=ord('F'),
101  PG_DIAG_SOURCE_LINE=ord('L'),
102  PG_DIAG_SOURCE_FUNCTION=ord('R')
103  );
104 
105  TZPostgreSQLExecStatusType = (
106  PGRES_EMPTY_QUERY,
107  PGRES_COMMAND_OK, { a query command that doesn't return anything
108  was executed properly by the backend }
109  PGRES_TUPLES_OK, { a query command that returns tuples
110  was executed properly by the backend,
111  PGresult contains the result tuples }
112  PGRES_COPY_OUT, { Copy Out data transfer in progress }
113  PGRES_COPY_IN, { Copy In data transfer in progress }
114  PGRES_BAD_RESPONSE, { an unexpected response was recv'd from
115  the backend }
116  PGRES_NONFATAL_ERROR,
117  PGRES_FATAL_ERROR
118  );
119 
120 { PGnotify represents the occurrence of a NOTIFY message.
121  Ideally this would be an opaque typedef, but it's so simple that it's
122  unlikely to change.
123  NOTE: in Postgres 6.4 and later, the be_pid is the notifying backend's,
124  whereas in earlier versions it was always your own backend's PID.
125 }
126  TZPostgreSQLNotify = packed record
127  relname: PAnsiChar; { name of relation containing data }
128  be_pid: Integer; { process id of backend }
129  payload: PAnsiChar; {additional data in notify}
130  end;
131 
132  PZPostgreSQLNotify = ^TZPostgreSQLNotify;
133 
134 { PQnoticeProcessor is the function type for the notice-message callback. }
135 
136  TZPostgreSQLNoticeProcessor = procedure(arg: Pointer; message: PAnsiChar); cdecl;
137 
138 { Structure for the conninfo parameter definitions returned by PQconndefaults }
139 
140  TZPostgreSQLConnectInfoOption = packed record
141  keyword: PAnsiChar; { The keyword of the option }
142  envvar: PAnsiChar; { Fallback environment variable name }
143  compiled: PAnsiChar; { Fallback compiled in default value }
144  val: PAnsiChar; { Options value }
145  lab: PAnsiChar; { Label for field in connect dialog }
146  disPAnsiChar: PAnsiChar; { Character to display for this field
147  in a connect dialog. Values are:
148  "" Display entered value as is
149  "*" Password field - hide value
150  "D" Debug options - don't
151  create a field by default }
152  dispsize: Integer; { Field size in characters for dialog }
153  end;
154 
155  PZPostgreSQLConnectInfoOption = ^TZPostgreSQLConnectInfoOption;
156 
157 { PQArgBlock -- structure for PQfn() arguments }
158 
159  TZPostgreSQLArgBlock = packed record
160  len: Integer;
161  isint: Integer;
162  case u: Boolean of
163  True: (ptr: PInteger); { can't use void (dec compiler barfs) }
164  False: (_int: Integer);
165  end;
166 
167  PZPostgreSQLArgBlock = ^TZPostgreSQLArgBlock;
168 
169  PZPostgreSQLConnect = Pointer;
170  PZPostgreSQLResult = Pointer;
171  PZPostgreSQLCancel = Pointer;
172  POid = ^Oid;
173  Oid = Integer;
174 
175 TZPgCharactersetType = (
176  csSQL_ASCII = 0, { SQL/ASCII }
177  csEUC_JP, { EUC for Japanese }
178  csEUC_CN, { EUC for Chinese }
179  csEUC_KR, { EUC for Korean }
180  csEUC_TW, { EUC for Taiwan }
181  csEUC_JIS_2004, {Extended UNIX Code-JP, JIS X 0213 Japanese}
182  csUTF8, { Unicode UTF-8 }
183  csMULE_INTERNAL, { Mule internal code }
184  csLATIN1, { ISO-8859 Latin 1 }
185  csLATIN2, { ISO-8859 Latin 2 }
186  csLATIN3, { ISO-8859 Latin 3 }
187  csLATIN4, { ISO-8859 Latin 4 }
188  csLATIN5, { ISO-8859 Latin 5 }
189  csLATIN6, { ISO-8859 Latin 6 }
190  csLATIN7, { ISO-8859 Latin 7 }
191  csLATIN8, { ISO-8859 Latin 8 }
192  csLATIN9, { ISO-8859 Latin 9 }
193  csLATIN10, { ISO-8859 Latin 10 }
194  csWIN1256, { Arabic Windows }
195  csWIN1258, { Vietnamese Windows }
196  csWIN866, { Alternativny Variant (MS-DOS CP866) }
197  csWIN874, { Thai Windows }
198  csKOI8, {KOI8-R(U) Cyrillic}
199  csKOI8R, { KOI8-R Cyrillic (Russian) }
200  csWIN1251, { windows-1251 }
201  csWIN1252, {Windows CP1252 Western European}
202  csISO_8859_5, { ISO-8859-5 }
203  csISO_8859_6, { ISO-8859-6 }
204  csISO_8859_7, { ISO-8859-7 }
205  csISO_8859_8, { ISO-8859-8 }
206  csWIN1250, { Windows CP1250 Central European }
207  csWIN1253, { Windows CP1253 Greek }
208  csWIN1254, { Windows CP1254 Turkish }
209  csWIN1255, { Windows CP1255 Hebrew }
210  csWIN1257, { Windows CP1257 Baltic }
211  csKOI8U, { KOI8-R Cyrillic (Ukrainian) }
212  csSJIS, { Shift JIS Japanese }
213  csBIG5, { Big Five Traditional Chinese }
214  csGBK, { Extended National Standard Simplified Chinese }
215  csUHC, { Unified Hangul Code Korean }
216  csGB18030, { National Standard Chinese }
217  csJOHAB, {JOHAB Korean (Hangul)}
218  csSHIFT_JIS_2004, {Shift JIS, JIS X 0213 Japanese}
219  csUNICODE_PODBC,{ UNICODE ( < Ver8.1). Can't call it UNICODE as that's already used }
220  csTCVN, { TCVN ( < Ver8.1) }
221  csALT, { ALT ( < Var8.1) }
222  csWIN, { WIN ( < Ver8.1) }
223  csOTHER
224 );
225 
226 { ****************** Plain API Types definition ***************** }
227 
228 type
229 { String descriptions of the ExecStatusTypes }
230  pgresStatus = array[$00..$ff] of PAnsiChar;
231 
232 { PGconn encapsulates a connection to the backend.
233  The contents of this struct are not supposed to be known to applications.
234 }
235  PGconn = Pointer;
236  PPGconn = Pointer;
237 
238 { PGresult encapsulates the result of a query (or more precisely, of a single
239  SQL command --- a query string given to PQsendQuery can contain multiple
240  commands and thus return multiple PGresult objects).
241  The contents of this struct are not supposed to be known to applications.
242 }
243  PGresult = Pointer;
244  PPGresult = Pointer;
245  PGCancel = Pointer;
246 
247 { PGnotify represents the occurrence of a NOTIFY message.
248  Ideally this would be an opaque typedef, but it's so simple that it's
249  unlikely to change.
250  NOTE: in Postgres 6.4 and later, the be_pid is the notifying backend's,
251  whereas in earlier versions it was always your own backend's PID.
252 }
253  PGnotify = packed record
254  relname: array [0..NAMEDATALEN-1] of AnsiChar; { name of relation containing data }
255  be_pid: Integer; { process id of backend }
256  end;
257 
258  PPGnotify = ^PGnotify;
259 
260 { PQnoticeProcessor is the function type for the notice-message callback. }
261 
262  PQnoticeProcessor = procedure(arg: Pointer; message: PAnsiChar); cdecl;
263 
264 { Print options for PQprint() }
265 
266 {
267  We can't use the conventional "bool", because we are designed to be
268  included in a user's program, and user may already have that type
269  defined. Pqbool, on the other hand, is unlikely to be used.
270 }
271 
272  PPAnsiChar = array[00..$ff] of PAnsiChar;
273 
274  PQprintOpt = packed record
275  header: Byte; { print output field headings and row count }
276  align: Byte; { fill align the fields }
277  standard: Byte; { old brain dead format }
278  html3: Byte; { output html tables }
279  expanded: Byte; { expand tables }
280  pager: Byte; { use pager for output if needed }
281  fieldSep: PAnsiChar; { field separator }
282  tableOpt: PAnsiChar; { insert to HTML <table ...> }
283  caption: PAnsiChar; { HTML <caption> }
284  fieldName: PPAnsiChar; { null terminated array of repalcement field names }
285  end;
286 
287  PPQprintOpt = ^PQprintOpt;
288 
289 { ----------------
290  Structure for the conninfo parameter definitions returned by PQconndefaults
291  ----------------
292 }
293  PQconninfoOption = packed record
294  keyword: PAnsiChar; { The keyword of the option }
295  envvar: PAnsiChar; { Fallback environment variable name }
296  compiled: PAnsiChar; { Fallback compiled in default value }
297  val: PAnsiChar; { Options value }
298  lab: PAnsiChar; { Label for field in connect dialog }
299  disPAnsiChar: PAnsiChar; { Character to display for this field
300  in a connect dialog. Values are:
301  "" Display entered value as is
302  "*" Password field - hide value
303  "D" Debug options - don't
304  create a field by default }
305  dispsize: Integer; { Field size in characters for dialog }
306  end;
307 
308  PPQConninfoOption = ^PQconninfoOption;
309 
310 { ----------------
311  PQArgBlock -- structure for PQfn() arguments
312  ----------------
313 }
314  PQArgBlock = packed record
315  len: Integer;
316  isint: Integer;
317  case u: Boolean of
318  True: (ptr: PInteger); { can't use void (dec compiler barfs) }
319  False: (_int: Integer);
320  end;
321 
322  PPQArgBlock = ^PQArgBlock;
323 
324 {Prepared statement types}
325  TPQparamTypes = {array of }POid;
326  TPQparamValues = array of PAnsichar;
327  TPQparamLengths = array of Integer;
328  TPQparamFormats = array of Integer;
329 
330 
331 { ************** Plain API Function types definition ************* }
332 { === in fe-connect.c === }
333  TPQconnectdb = function(ConnInfo: PAnsiChar): PPGconn; cdecl; // FirmOS 8.1 OK
334  TPQsetdbLogin = function(Host, Port, Options, Tty, Db, User, Passwd: PAnsiChar): PPGconn; cdecl; // FirmOS 8.1 OK
335 //15022006 FirmOS: omitting PQconnectStart
336 //15022006 FirmOS: omitting PQconnectPoll
337  TPQconndefaults = function: PPQconninfoOption; cdecl;
338  TPQfinish = procedure(Handle: PPGconn); cdecl;
339  TPQreset = procedure(Handle: PPGconn); cdecl;
340 //15022006 FirmOS: omitting PQresetStart
341 //15022006 FirmOS: omitting PQresetPoll
342  TPQrequestCancel = function(Handle: PPGconn): Integer; cdecl;
343  TPQdb = function(Handle: PPGconn): PAnsiChar; cdecl;
344  TPQuser = function(Handle: PPGconn): PAnsiChar; cdecl;
345  TPQpass = function(Handle: PPGconn): PAnsiChar; cdecl;
346  TPQhost = function(Handle: PPGconn): PAnsiChar; cdecl;
347  TPQport = function(Handle: PPGconn): PAnsiChar; cdecl;
348  TPQtty = function(Handle: PPGconn): PAnsiChar; cdecl;
349  TPQoptions = function(Handle: PPGconn): PAnsiChar; cdecl;
350  TPQstatus = function(Handle: PPGconn): TZPostgreSQLConnectStatusType; cdecl;
351 //TBD PGTransactionStatusType PQtransactionStatus(const PGconn *conn);
352 //15022006 FirmOS: omitting const char *PQparameterStatus(const PGconn *conn, const char *paramName);
353 //15022006 FirmOS: omitting PQprotocolVersion
354  TPQserverVersion = function(Handle: PPGconn): Integer; cdecl;
355  TPQerrorMessage = function(Handle: PPGconn): PAnsiChar; cdecl;
356  TPQsocket = function(Handle: PPGconn): Integer; cdecl;
357  TPQbackendPID = function(Handle: PPGconn): Integer; cdecl;
358 //15022006 FirmOS: omitting SSL *PQgetssl(const PGconn *conn);
359  TPQtrace = procedure(Handle: PPGconn; DebugPort: Pointer); cdecl;
360  TPQuntrace = procedure(Handle: PPGconn); cdecl;
361  TPQsetNoticeProcessor = procedure(Handle: PPGconn; Proc: PQnoticeProcessor; Arg: Pointer); cdecl;
362 
363  TPQclientEncoding = function(Handle: PPGconn): Integer; cdecl; //EgonHugeist
364 { === in fe-exec.c === }
365 //* Simple synchronous query */
366  TPQexec = function(Handle: PPGconn; Query: PAnsiChar): PPGresult; cdecl;
367  TPQexecParams = function(Handle: PPGconn; command: PAnsichar;
368  nParams: Integer; paramTypes: TPQparamTypes; paramValues: TPQparamValues;
369  paramLengths: TPQparamLengths; paramFormats: TPQparamFormats;
370  resultFormat: Integer): PPGresult; cdecl;
371  TPQprepare = function(Handle: PPGconn; stmtName: PAnsichar;
372  query: PAnsiChar; nParams: Integer; paramTypes: TPQparamTypes): PPGresult; cdecl;
373  TPQexecPrepared = function(Handle: PPGconn; stmtName: PAnsichar;
374  nParams: Integer; paramValues: TPQparamValues; paramLengths: TPQparamLengths;
375  paramFormats: TPQparamFormats; resultFormat: Integer): PPGresult; cdecl;
376 //* Interface for multiple-result or asynchronous queries */
377  TPQsendQuery = function(Handle: PPGconn; query: PAnsiChar): Integer; cdecl;
378  TPQsendQueryParams= function(Handle: PPGconn; command: PAnsichar;
379  nParams: Integer; paramTypes: TPQparamTypes; paramValues: TPQparamValues;
380  paramLengths: TPQparamLengths; paramFormats: TPQparamFormats;
381  resultFormat: Integer): Integer; cdecl;
382  TPQsendPrepare = function(Handle: PPGconn; stmtName: PAnsichar;
383  query: PAnsiChar; nParams: Integer; paramTypes: TPQparamTypes): Integer; cdecl;
384  TPQsendQueryPrepared = function(Handle: PPGconn; stmtName: PAnsichar;
385  nParams: Integer; paramValues: TPQparamValues;
386  paramLengths: TPQparamLengths; paramFormats: TPQparamFormats;
387  resultFormat: Integer): Integer; cdecl;
388  TPQgetResult = function(Handle: PPGconn): PPGresult; cdecl;
389 //* Describe prepared statements and portals */
390  TPQdescribePrepared = function(Handle: PPGconn; const stmt: PAnsiChar): PPGresult; cdecl;
391  TPQdescribePortal = function(Handle: PPGconn; const portal: PAnsiChar): PPGresult; cdecl;
392  TPQsendDescribePrepared = function(Handle: PPGconn; const stmt: PAnsiChar): Integer; cdecl;
393  TPQsendDescribePortal = function(Handle: PPGconn; const portal: PAnsiChar): Integer; cdecl;
394 
395  TPQnotifies = function(Handle: PPGconn): PPGnotify; cdecl;
396  TPQfreeNotify = procedure(Handle: PPGnotify);cdecl;
397  TPQisBusy = function(Handle: PPGconn): Integer; cdecl;
398  TPQconsumeInput = function(Handle: PPGconn): Integer; cdecl;
399  TPQgetCancel = function(Handle: PPGconn): PGcancel; cdecl;
400  TPQfreeCancel = procedure(Canc: PGcancel); cdecl;
401  TPQcancel = function(Canc: PGcancel; Buffer: PChar; BufSize: Integer): Integer;
402  TPQgetline = function(Handle: PPGconn; Str: PAnsiChar; length: Integer): Integer; cdecl;
403  TPQputline = function(Handle: PPGconn; Str: PAnsiChar): Integer; cdecl;
404  TPQgetlineAsync = function(Handle: PPGconn; Buffer: PAnsiChar; BufSize: Integer): Integer; cdecl;
405  TPQputnbytes = function(Handle: PPGconn; Buffer: PAnsiChar; NBytes: Integer): Integer; cdecl;
406  TPQendcopy = function(Handle: PPGconn): Integer; cdecl;
407  TPQfn = function(Handle: PPGconn; fnid: Integer; result_buf, result_len: PInteger; result_is_int: Integer; args: PPQArgBlock; nargs: Integer): PPGresult; cdecl;
408  TPQresultStatus = function(Result: PPGresult): TZPostgreSQLExecStatusType; cdecl;
409  TPQresultErrorMessage = function(Result: PPGresult): PAnsiChar; cdecl;
410  TPQresultErrorField=function(result: PPGResult; fieldcode:integer):PAnsiChar;cdecl; // postgresql 8
411  TPQntuples = function(Result: PPGresult): Integer; cdecl;
412  TPQnfields = function(Result: PPGresult): Integer; cdecl;
413  TPQbinaryTuples = function(Result: PPGresult): Integer; cdecl;
414  TPQfname = function(Result: PPGresult; field_num: Integer): PAnsiChar; cdecl;
415  TPQfnumber = function(Result: PPGresult; field_name: PAnsiChar): Integer; cdecl;
416  TPQftable = function(Result: PPGresult; field_num: Integer): Oid; cdecl;
417  TPQftablecol = function(Result: PPGresult; field_num: Integer): Integer; cdecl;
418  TPQftype = function(Result: PPGresult; field_num: Integer): Oid; cdecl;
419  TPQfsize = function(Result: PPGresult; field_num: Integer): Integer; cdecl;
420  TPQfmod = function(Result: PPGresult; field_num: Integer): Integer; cdecl;
421  TPQcmdStatus = function(Result: PPGresult): PAnsiChar; cdecl;
422  TPQoidValue = function(Result: PPGresult): Oid; cdecl;
423  TPQoidStatus = function(Result: PPGresult): PAnsiChar; cdecl;
424  TPQcmdTuples = function(Result: PPGresult): PAnsiChar; cdecl;
425  TPQgetvalue = function(Result: PPGresult; tup_num, field_num: Integer): PAnsiChar; cdecl;
426  TPQgetlength = function(Result: PPGresult; tup_num, field_num: Integer): Integer; cdecl;
427  TPQgetisnull = function(Result: PPGresult; tup_num, field_num: Integer): Integer; cdecl;
428  TPQclear = procedure(Result: PPGresult); cdecl;
429  TPQmakeEmptyPGresult = function(Handle: PPGconn; status: TZPostgreSQLExecStatusType): PPGresult; cdecl;
430  //* Quoting strings before inclusion in queries. */
431  // postgresql 8
432  TPQescapeStringConn = function(Handle: PGconn; ToChar: PAnsiChar;
433  const FromChar: PAnsiChar; length: NativeUInt; error: PInteger): NativeUInt;cdecl; //7.3
434  TPQescapeLiteral = function(Handle: PGconn; const str: PAnsiChar; len: NativeUInt): PAnsiChar;cdecl;
435  TPQescapeIdentifier = function(Handle: PGconn; const str: PAnsiChar; len: NativeUInt): PAnsiChar;cdecl; //7.3
436  TPQescapeByteaConn = function(Handle: PPGconn;const from:PAnsiChar;from_length:longword;to_lenght:PLongword):PAnsiChar;cdecl;
437  TPQunescapeBytea = function(const from:PAnsiChar;to_lenght:PLongword):PAnsiChar;cdecl;
438  TPQFreemem = procedure(ptr:Pointer);cdecl;
439 
440  //* These forms are deprecated! */
441  TPQescapeString = function(ToChar: PAnsiChar; const FormChar: PAnsiChar; length: NativeUInt): NativeUInt;cdecl; //7.2
442  TPQescapeBytea = function(const from:PAnsiChar;from_length:longword;to_lenght:PLongword):PAnsiChar;cdecl; //7.2
443 
444  { === in fe-lobj.c === }
445  Tlo_open = function(Handle: PPGconn; lobjId: Oid; mode: Integer): Integer; cdecl;
446  Tlo_close = function(Handle: PPGconn; fd: Integer): Integer; cdecl;
447  Tlo_read = function(Handle: PPGconn; fd: Integer; buf: PAnsiChar; len: NativeUInt): Integer; cdecl;
448  Tlo_write = function(Handle: PPGconn; fd: Integer; buf: PAnsiChar; len: NativeUInt): Integer; cdecl;
449  Tlo_lseek = function(Handle: PPGconn; fd, offset, whence: Integer): Integer; cdecl;
450  Tlo_creat = function(Handle: PPGconn; mode: Integer): Oid; cdecl;
451  Tlo_tell = function(Handle: PPGconn; fd: Integer): Integer; cdecl;
452  Tlo_unlink = function(Handle: PPGconn; lobjId: Oid): Integer; cdecl;
453  Tlo_import = function(Handle: PPGconn; filename: PAnsiChar): Oid; cdecl;
454  Tlo_export = function(Handle: PPGconn; lobjId: Oid; filename: PAnsiChar): Integer; cdecl;
455 
456 { ************** Collection of Plain API Function types definition ************* }
457 TZPOSTGRESQL_API = record
458 { === in fe-connect.c === }
459  PQconnectdb: TPQconnectdb;
460  PQsetdbLogin: TPQsetdbLogin;
461  PQconndefaults: TPQconndefaults;
462  PQfinish: TPQfinish;
463  PQreset: TPQreset;
464  PQrequestCancel: TPQrequestCancel;
465  PQdb: TPQdb;
466  PQuser: TPQuser;
467  PQpass: TPQpass;
468  PQhost: TPQhost;
469  PQport: TPQport;
470  PQtty: TPQtty;
471  PQoptions: TPQoptions;
472  PQstatus: TPQstatus;
473  PQserverVersion: TPQserverVersion;
474  PQerrorMessage: TPQerrorMessage;
475  PQsocket: TPQsocket;
476  PQbackendPID: TPQbackendPID;
477  PQtrace: TPQtrace;
478  PQuntrace: TPQuntrace;
479  PQsetNoticeProcessor: TPQsetNoticeProcessor;
480  PQclientEncoding: TPQclientEncoding;
481 { === in fe-exec.c === }
482  PQexec: TPQexec;
483  PQexecParams: TPQexecParams;
484  PQprepare: TPQprepare;
485  PQexecPrepared: TPQexecPrepared;
486  PQsendQuery: TPQsendQuery;
487  PQsendQueryParams: TPQsendQueryParams;
488  PQsendPrepare: TPQsendPrepare;
489  PQsendQueryPrepared: TPQsendQueryPrepared;
490  PQgetResult: TPQgetResult;
491  //* Describe prepared statements and portals */
492  PQdescribePrepared: TPQdescribePrepared;
493  PQdescribePortal: TPQdescribePortal;
494  PQsendDescribePrepared: TPQsendDescribePrepared;
495  PQsendDescribePortal: TPQsendDescribePortal;
496  PQnotifies: TPQnotifies;
497  PQfreeNotify: TPQfreeNotify;
498  PQisBusy: TPQisBusy;
499  PQconsumeInput: TPQconsumeInput;
500  PQgetCancel: TPQgetCancel;
501  PQfreeCancel: TPQfreeCancel;
502  PQcancel: TPQcancel;
503  PQgetline: TPQgetline;
504  PQputline: TPQputline;
505  PQgetlineAsync: TPQgetlineAsync;
506  PQputnbytes: TPQputnbytes;
507  PQendcopy: TPQendcopy;
508  PQfn: TPQfn;
509  PQresultStatus: TPQresultStatus;
510  PQresultErrorMessage: TPQresultErrorMessage;
511  PQresultErrorField: TPQresultErrorField; // postgresql 8
512  PQntuples: TPQntuples;
513  PQnfields: TPQnfields;
514  PQbinaryTuples: TPQbinaryTuples;
515  PQfname: TPQfname;
516  PQfnumber: TPQfnumber;
517  PQftable: TPQftable;
518  PQftablecol: TPQftablecol;
519  PQftype: TPQftype;
520  PQfsize: TPQfsize;
521  PQfmod: TPQfmod;
522  PQcmdStatus: TPQcmdStatus;
523  PQoidValue: TPQoidValue;
524  PQoidStatus: TPQoidStatus;
525  PQcmdTuples: TPQcmdTuples;
526  PQgetvalue: TPQgetvalue;
527  PQgetlength: TPQgetlength;
528  PQgetisnull: TPQgetisnull;
529  PQclear: TPQclear;
530  PQmakeEmptyPGresult: TPQmakeEmptyPGresult;
531 
532  PQescapeStringConn: TPQescapeStringConn; //since 7.3
533  PQescapeByteaConn: TPQescapeByteaConn; // postgresql since 7.3
534  PQFreemem: TPQFreemem; // since postgresql 7.4
535  PQescapeString: TPQescapeString; // since postgresql 7.4
536  PQescapeBytea: TPQescapeBytea; // since postgresql 7.4
537  PQunescapeBytea: TPQunescapeBytea; // since postgresql 8.3
538  PQescapeLiteral: TPQescapeLiteral; // since postgresql 9.0
539  PQescapeIdentifier: TPQescapeIdentifier; // since postgresql 9.0
540 
541 { === in fe-lobj.c === }
542  lo_open: Tlo_open;
543  lo_close: Tlo_close;
544  lo_read: Tlo_read;
545  lo_write: Tlo_write;
546  lo_lseek: Tlo_lseek;
547  lo_creat: Tlo_creat;
548  lo_tell: Tlo_tell;
549  lo_unlink: Tlo_unlink;
550  lo_import: Tlo_import;
551  lo_export: Tlo_export;
552 end;
553 
554 PAPI = ^TZPOSTGRESQL_API;
555 
556 type
557 
558  {** Represents a generic interface to PostgreSQL native API. }
559  IZPostgreSQLPlainDriver = interface (IZPlainDriver)
560  ['{03CD6345-2D7A-4FE2-B03D-3C5656789FEB}']
561 
562  function GetStandardConformingStrings: Boolean;
563 
564  function EncodeBYTEA(const Value: RawByteString; Handle: PZPostgreSQLConnect;
565  Quoted: Boolean = True): RawByteString;
566  function DecodeBYTEA(const value: RawByteString; const Is_bytea_output_hex: Boolean;
567  Handle: PZPostgreSQLConnect): RawByteString;
568  function SupportsEncodeBYTEA: Boolean;
569  function SupportsDecodeBYTEA(const Handle: PZPostgreSQLConnect): Boolean;
570  function SupportsStringEscaping(const ClientDependend: Boolean): Boolean;
571 
572  function ConnectDatabase(ConnInfo: PAnsiChar): PZPostgreSQLConnect;
573  function SetDatabaseLogin(Host, Port, Options, TTY, Db, User,Passwd: PAnsiChar): PZPostgreSQLConnect;
574  function GetConnectDefaults: PZPostgreSQLConnectInfoOption;
575 
576  procedure Finish(Handle: PZPostgreSQLConnect);
577  procedure Reset(Handle: PZPostgreSQLConnect);
578  function RequestCancel(Handle: PZPostgreSQLConnect): Integer;
579  function GetDatabase(Handle: PZPostgreSQLConnect): PAnsiChar;
580  function GetUser(Handle: PZPostgreSQLConnect): PAnsiChar;
581  function GetPassword(Handle: PZPostgreSQLConnect): PAnsiChar;
582  function GetHost(Handle: PZPostgreSQLConnect): PAnsiChar;
583  function GetPort(Handle: PZPostgreSQLConnect): PAnsiChar;
584  function GetTTY(Handle: PZPostgreSQLConnect): PAnsiChar;
585  function GetOptions(Handle: PZPostgreSQLConnect): PAnsiChar;
586  function GetStatus(Handle: PZPostgreSQLConnect):TZPostgreSQLConnectStatusType;
587  function GetClientEncoding(Handle: PPGconn): Integer; //EgonHugeist
588 
589  function GetErrorMessage(Handle: PZPostgreSQLConnect): PAnsiChar;
590  function GetSocket(Handle: PZPostgreSQLConnect): Integer;
591  function GetBackendPID(Handle: PZPostgreSQLConnect): Integer;
592  procedure Trace(Handle: PZPostgreSQLConnect; DebugPort: Pointer);
593  procedure Untrace(Handle: PZPostgreSQLConnect);
594  procedure SetNoticeProcessor(Handle: PZPostgreSQLConnect;Proc: TZPostgreSQLNoticeProcessor; Arg: Pointer);
595 
596  function ExecuteQuery(Handle: PZPostgreSQLConnect;Query: PAnsiChar): PZPostgreSQLResult;
597  function ExecParams(Handle: PPGconn; command: PAnsichar;
598  nParams: Integer; paramTypes: TPQparamTypes; paramValues: TPQparamValues;
599  paramLengths: TPQparamLengths; paramFormats: TPQparamFormats;
600  resultFormat: Integer): PPGresult;
601  function Prepare(Handle: PPGconn; stmtName: PAnsichar;
602  query: PAnsiChar; nParams: Integer; paramTypes: TPQparamTypes): PPGresult;
603  function ExecPrepared(Handle: PPGconn; stmtName: PAnsichar;
604  nParams: Integer; paramValues: TPQparamValues; paramLengths: TPQparamLengths;
605  paramFormats: TPQparamFormats; resultFormat: Integer): PPGresult;
606  function SendQuery(Handle: PZPostgreSQLConnect; Query: PAnsiChar): Integer;
607  function SendQueryParams(Handle: PPGconn; command: PAnsichar;
608  nParams: Integer; paramTypes: TPQparamTypes; paramValues: TPQparamValues;
609  paramLengths: TPQparamLengths; paramFormats: TPQparamFormats;
610  resultFormat: Integer): Integer;
611  function SendPrepare(Handle: PPGconn; stmtName: PAnsichar;
612  query: PAnsiChar; nParams: Integer; paramTypes: TPQparamTypes): Integer;
613  function SendQueryPrepared(Handle: PPGconn; stmtName: PAnsichar;
614  nParams: Integer; paramValues: TPQparamValues;
615  paramLengths: TPQparamLengths; paramFormats: TPQparamFormats;
616  resultFormat: Integer): Integer;
617  function GetResult(Handle: PZPostgreSQLConnect): PZPostgreSQLResult;
618  //* Describe prepared statements and portals */
619  function DescribePrepared(Handle: PPGconn; const stmt: PAnsiChar): PPGresult;
620  function DescribePortal(Handle: PPGconn; const portal: PAnsiChar): PPGresult;
621  function SendDescribePrepared(Handle: PPGconn; const stmt: PAnsiChar): Integer;
622  function SendDescribePortal(Handle: PPGconn; const portal: PAnsiChar): Integer;
623  function Notifies(Handle: PZPostgreSQLConnect): PZPostgreSQLNotify;
624  procedure FreeNotify(Handle: PZPostgreSQLNotify);
625 
626  function IsBusy(Handle: PZPostgreSQLConnect): Integer;
627  function ConsumeInput(Handle: PZPostgreSQLConnect): Integer;
628  function GetCancel(Handle: PZPostgreSQLConnect): PZPostgreSQLCancel;
629  procedure FreeCancel( Canc: PZPostgreSQLCancel);
630  function Cancel( Canc: PZPostgreSQLCancel; Buffer: PChar; Length: Integer): Integer;
631  function GetLine(Handle: PZPostgreSQLConnect; Str: PAnsiChar;
632  Length: Integer): Integer;
633  function PutLine(Handle: PZPostgreSQLConnect; Str: PAnsiChar): Integer;
634  function GetLineAsync(Handle: PZPostgreSQLConnect; Buffer: PAnsiChar;
635  Length: Integer): Integer;
636 
637  function PutBytes(Handle: PZPostgreSQLConnect; Buffer: PAnsiChar;
638  Length: Integer): Integer;
639  function EndCopy(Handle: PZPostgreSQLConnect): Integer;
640  function ExecuteFunction(Handle: PZPostgreSQLConnect; fnid: Integer;
641  result_buf, result_len: PInteger; result_is_int: Integer;
642  args: PZPostgreSQLArgBlock; nargs: Integer): PZPostgreSQLResult;
643  function GetResultStatus(Res: PZPostgreSQLResult):
644  TZPostgreSQLExecStatusType;
645 
646  function GetResultErrorMessage(Res: PZPostgreSQLResult): PAnsiChar;
647  function GetResultErrorField(Res: PZPostgreSQLResult; FieldCode: TZPostgreSQLFieldCode): PAnsiChar;
648 
649  function GetRowCount(Res: PZPostgreSQLResult): Integer;
650  function GetFieldCount(Res: PZPostgreSQLResult): Integer;
651 
652  function GetBinaryTuples(Res: PZPostgreSQLResult): Integer;
653  function GetFieldName(Res: PZPostgreSQLResult; FieldNum: Integer): PAnsiChar;
654  function GetFieldNumber(Res: PZPostgreSQLResult; FieldName: PAnsiChar): Integer;
655  function GetFieldTableOID(Res: PZPostgreSQLResult; FieldNum: Integer) : Oid;
656  function GetFieldTableColIdx(Res: PZPostgreSQLResult; FieldNum: Integer) : Integer;
657  function GetFieldType(Res: PZPostgreSQLResult; FieldNum: Integer): Oid;
658  function GetFieldSize(Res: PZPostgreSQLResult; FieldNum: Integer): Integer;
659  function GetFieldMode(Res: PZPostgreSQLResult; FieldNum: Integer): Integer;
660  function GetCommandStatus(Res: PZPostgreSQLResult): PAnsiChar;
661  function GetOidValue(Res: PZPostgreSQLResult): Oid;
662  function GetOidStatus(Res: PZPostgreSQLResult): PAnsiChar;
663  function GetCommandTuples(Res: PZPostgreSQLResult): PAnsiChar;
664 
665  function GetValue(Res: PZPostgreSQLResult; TupNum, FieldNum: Integer): PAnsiChar;
666  function GetLength(Res: PZPostgreSQLResult; TupNum, FieldNum: Integer): Integer;
667  function GetIsNull(Res: PZPostgreSQLResult; TupNum, FieldNum: Integer): Integer;
668  procedure Clear(Res: PZPostgreSQLResult);
669 
670  function MakeEmptyResult(Handle: PZPostgreSQLConnect;
671  Status: TZPostgreSQLExecStatusType): PZPostgreSQLResult;
672 
673  function OpenLargeObject(Handle: PZPostgreSQLConnect; ObjId: Oid;
674  Mode: Integer): Integer;
675  function CloseLargeObject(Handle: PZPostgreSQLConnect;
676  Fd: Integer): Integer;
677  function ReadLargeObject(Handle: PZPostgreSQLConnect; Fd: Integer;
678  Buffer: PAnsiChar; Length: Integer): Integer;
679  function WriteLargeObject(Handle: PZPostgreSQLConnect; Fd: Integer;
680  Buffer: PAnsiChar; Length: Integer): Integer;
681  function SeekLargeObject(Handle: PZPostgreSQLConnect;
682  Fd, Offset, Whence: Integer): Integer;
683  function CreateLargeObject(Handle: PZPostgreSQLConnect;
684  Mode: Integer): Oid;
685  function TellLargeObject(Handle: PZPostgreSQLConnect;
686  Fd: Integer): Integer;
687  function UnlinkLargeObject(Handle: PZPostgreSQLConnect;
688  ObjId: Oid): Integer;
689  function ImportLargeObject(Handle: PZPostgreSQLConnect;
690  FileName: PAnsiChar): Oid;
691  function ExportLargeObject(Handle: PZPostgreSQLConnect; ObjId: Oid;
692  FileName: PAnsiChar): Integer;
693  function GetPlainFunc:PAPI;
694  end;
695 
696  {** Implements a base driver for PostgreSQL}
697  TZPostgreSQLBaseDriver = class(TZAbstractPlainDriver, IZPostgreSQLPlainDriver)
698  protected
699  POSTGRESQL_API: TZPOSTGRESQL_API;
700  function GetStandardConformingStrings: Boolean; virtual;
701  function GetUnicodeCodePageName: String; override;
702  procedure LoadCodePages; override;
703  procedure LoadApi; override;
704  public
705  constructor Create;
706 
707  function EncodeBYTEA(const Value: RawByteString; Handle: PZPostgreSQLConnect;
708  Quoted: Boolean = True): RawByteString;
709  function DecodeBYTEA(const value: RawByteString; const Is_bytea_output_hex: Boolean;
710  Handle: PZPostgreSQLConnect): RawByteString;
711 
712  function SupportsEncodeBYTEA: Boolean;
713  function SupportsDecodeBYTEA(const Handle: PZPostgreSQLConnect): Boolean;
714  function SupportsStringEscaping(const ClientDependend: Boolean): Boolean;
715 
716  function ConnectDatabase(ConnInfo: PAnsiChar): PZPostgreSQLConnect;
717  function SetDatabaseLogin(Host, Port, Options, TTY, Db, User,
718  Passwd: PAnsiChar): PZPostgreSQLConnect;
719  function GetConnectDefaults: PZPostgreSQLConnectInfoOption;
720 
721  procedure Finish(Handle: PZPostgreSQLConnect);
722  procedure Reset(Handle: PZPostgreSQLConnect);
723  function RequestCancel(Handle: PZPostgreSQLConnect): Integer;
724  function GetDatabase(Handle: PZPostgreSQLConnect): PAnsiChar;
725  function GetUser(Handle: PZPostgreSQLConnect): PAnsiChar;
726  function GetPassword(Handle: PZPostgreSQLConnect): PAnsiChar;
727  function GetHost(Handle: PZPostgreSQLConnect): PAnsiChar;
728  function GetPort(Handle: PZPostgreSQLConnect): PAnsiChar;
729  function GetTTY(Handle: PZPostgreSQLConnect): PAnsiChar;
730  function GetOptions(Handle: PZPostgreSQLConnect): PAnsiChar;
731  function GetStatus(Handle: PZPostgreSQLConnect):
732  TZPostgreSQLConnectStatusType;
733  function GetClientEncoding(Handle: PPGconn): Integer; //EgonHugeist
734 
735  function GetErrorMessage(Handle: PZPostgreSQLConnect): PAnsiChar;
736  function GetSocket(Handle: PZPostgreSQLConnect): Integer;
737  function GetBackendPID(Handle: PZPostgreSQLConnect): Integer;
738  procedure Trace(Handle: PZPostgreSQLConnect; DebugPort: Pointer);
739  procedure Untrace(Handle: PZPostgreSQLConnect);
740  procedure SetNoticeProcessor(Handle: PZPostgreSQLConnect;
741  Proc: TZPostgreSQLNoticeProcessor; Arg: Pointer);
742 
743  function ExecuteQuery(Handle: PZPostgreSQLConnect;
744  Query: PAnsiChar): PZPostgreSQLResult;
745  function ExecParams(Handle: PPGconn; command: PAnsichar;
746  nParams: Integer; paramTypes: TPQparamTypes; paramValues: TPQparamValues;
747  paramLengths: TPQparamLengths; paramFormats: TPQparamFormats;
748  resultFormat: Integer): PPGresult;
749  function Prepare(Handle: PPGconn; stmtName: PAnsichar;
750  query: PAnsiChar; nParams: Integer; paramTypes: TPQparamTypes): PPGresult;
751  function ExecPrepared(Handle: PPGconn; stmtName: PAnsichar;
752  nParams: Integer; paramValues: TPQparamValues; paramLengths: TPQparamLengths;
753  paramFormats: TPQparamFormats; resultFormat: Integer): PPGresult;
754  function SendQuery(Handle: PZPostgreSQLConnect; Query: PAnsiChar): Integer;
755  function SendQueryParams(Handle: PPGconn; command: PAnsichar;
756  nParams: Integer; paramTypes: TPQparamTypes; paramValues: TPQparamValues;
757  paramLengths: TPQparamLengths; paramFormats: TPQparamFormats;
758  resultFormat: Integer): Integer;
759  function SendPrepare(Handle: PPGconn; stmtName: PAnsichar;
760  query: PAnsiChar; nParams: Integer; paramTypes: TPQparamTypes): Integer;
761  function SendQueryPrepared(Handle: PPGconn; stmtName: PAnsichar;
762  nParams: Integer; paramValues: TPQparamValues;
763  paramLengths: TPQparamLengths; paramFormats: TPQparamFormats;
764  resultFormat: Integer): Integer;
765  function GetResult(Handle: PZPostgreSQLConnect): PZPostgreSQLResult;
766  function DescribePrepared(Handle: PPGconn; const stmt: PAnsiChar): PPGresult;
767  function DescribePortal(Handle: PPGconn; const portal: PAnsiChar): PPGresult;
768  function SendDescribePrepared(Handle: PPGconn; const stmt: PAnsiChar): Integer;
769  function SendDescribePortal(Handle: PPGconn; const portal: PAnsiChar): Integer;
770 
771  function Notifies(Handle: PZPostgreSQLConnect): PZPostgreSQLNotify;
772  procedure FreeNotify(Handle: PZPostgreSQLNotify);
773 
774  function IsBusy(Handle: PZPostgreSQLConnect): Integer;
775  function ConsumeInput(Handle: PZPostgreSQLConnect): Integer;
776  function GetCancel(Handle: PZPostgreSQLConnect): PZPostgreSQLCancel;
777  procedure FreeCancel( Canc: PZPostgreSQLCancel);
778  function Cancel( Canc: PZPostgreSQLCancel; Buffer: PChar; Length: Integer): Integer;
779  function GetLine(Handle: PZPostgreSQLConnect; Buffer: PAnsiChar;
780  Length: Integer): Integer;
781  function PutLine(Handle: PZPostgreSQLConnect; Buffer: PAnsiChar): Integer;
782  function GetLineAsync(Handle: PZPostgreSQLConnect; Buffer: PAnsiChar;
783  Length: Integer): Integer;
784 
785  function PutBytes(Handle: PZPostgreSQLConnect; Buffer: PAnsiChar;
786  Length: Integer): Integer;
787  function EndCopy(Handle: PZPostgreSQLConnect): Integer;
788  function ExecuteFunction(Handle: PZPostgreSQLConnect; fnid: Integer;
789  result_buf, result_len: PInteger; result_is_int: Integer;
790  args: PZPostgreSQLArgBlock; nargs: Integer): PZPostgreSQLResult;
791  function GetResultStatus(Res: PZPostgreSQLResult): TZPostgreSQLExecStatusType;
792  function GetResultErrorMessage(Res: PZPostgreSQLResult): PAnsiChar;
793  function GetResultErrorField(Res: PZPostgreSQLResult;FieldCode:TZPostgreSQLFieldCode):PAnsiChar;
794 
795  function GetRowCount(Res: PZPostgreSQLResult): Integer;
796  function GetFieldCount(Res: PZPostgreSQLResult): Integer;
797 
798  function GetBinaryTuples(Res: PZPostgreSQLResult): Integer;
799  function GetFieldName(Res: PZPostgreSQLResult;
800  FieldNum: Integer): PAnsiChar;
801  function GetFieldNumber(Res: PZPostgreSQLResult;
802  FieldName: PAnsiChar): Integer;
803  function GetFieldTableOID(Res: PZPostgreSQLResult; FieldNum: Integer) : Oid;
804  function GetFieldTableColIdx(Res: PZPostgreSQLResult; FieldNum: Integer) : Integer;
805  function GetFieldType(Res: PZPostgreSQLResult;
806  FieldNum: Integer): Oid;
807  function GetFieldSize(Res: PZPostgreSQLResult;
808  FieldNum: Integer): Integer;
809  function GetFieldMode(Res: PZPostgreSQLResult;
810  FieldNum: Integer): Integer;
811  function GetCommandStatus(Res: PZPostgreSQLResult): PAnsiChar;
812  function GetOidValue(Res: PZPostgreSQLResult): Oid;
813  function GetOidStatus(Res: PZPostgreSQLResult): PAnsiChar;
814  function GetCommandTuples(Res: PZPostgreSQLResult): PAnsiChar;
815 
816  function GetValue(Res: PZPostgreSQLResult;
817  TupNum, FieldNum: Integer): PAnsiChar;
818  function GetLength(Res: PZPostgreSQLResult;
819  TupNum, FieldNum: Integer): Integer;
820  function GetIsNull(Res: PZPostgreSQLResult;
821  TupNum, FieldNum: Integer): Integer;
822  procedure Clear(Res: PZPostgreSQLResult);
823 
824  function MakeEmptyResult(Handle: PZPostgreSQLConnect;
825  Status: TZPostgreSQLExecStatusType): PZPostgreSQLResult;
826 
827  function OpenLargeObject(Handle: PZPostgreSQLConnect; ObjId: Oid;
828  Mode: Integer): Integer;
829  function CloseLargeObject(Handle: PZPostgreSQLConnect;
830  Fd: Integer): Integer;
831  function ReadLargeObject(Handle: PZPostgreSQLConnect; Fd: Integer;
832  Buffer: PAnsiChar; Length: Integer): Integer;
833  function WriteLargeObject(Handle: PZPostgreSQLConnect; Fd: Integer;
834  Buffer: PAnsiChar; Length: Integer): Integer;
835  function SeekLargeObject(Handle: PZPostgreSQLConnect;
836  Fd, Offset, Whence: Integer): Integer;
837  function CreateLargeObject(Handle: PZPostgreSQLConnect;
838  Mode: Integer): Oid;
839  function TellLargeObject(Handle: PZPostgreSQLConnect;
840  Fd: Integer): Integer;
841  function UnlinkLargeObject(Handle: PZPostgreSQLConnect;
842  ObjId: Oid): Integer;
843  function ImportLargeObject(Handle: PZPostgreSQLConnect;
844  FileName: PAnsiChar): Oid;
845  function ExportLargeObject(Handle: PZPostgreSQLConnect; ObjId: Oid;
846  FileName: PAnsiChar): Integer;
847  function GetPlainFunc:PAPI;
848  function EscapeString(Handle: Pointer; const Value: RawByteString;
849  ConSettings: PZConSettings; WasEncoded: Boolean = False): RawByteString; override;
850  end;
851 
852  {** Implements a driver for PostgreSQL 7.4 }
853  TZPostgreSQL7PlainDriver = class(TZPostgreSQLBaseDriver, IZPlainDriver,
854  IZPostgreSQLPlainDriver)
855  protected
856  function Clone: IZPlainDriver; override;
857  public
858  constructor Create;
859 
860  function GetProtocol: string; override;
861  function GetDescription: string; override;
862  end;
863 
864 
865  {** Implements a driver for PostgreSQL 8.1 }
866 
867  { TZPostgreSQL8PlainDriver }
868 
869  TZPostgreSQL8PlainDriver = class(TZPostgreSQLBaseDriver, IZPlainDriver,IZPostgreSQLPlainDriver)
870  protected
871  function Clone: IZPlainDriver; override;
872  function GetUnicodeCodePageName: String; override;
873  procedure LoadCodePages; override;
874  public
875  constructor Create;
876 
877  function GetProtocol: string; override;
878  function GetDescription: string; override;
879  end;
880 
881  { TZPostgreSQL8PlainDriver }
882 
883  TZPostgreSQL9PlainDriver = class(TZPostgreSQL8PlainDriver)
884  protected
885  function Clone: IZPlainDriver; override;
886  function GetStandardConformingStrings: Boolean; override;
887  procedure LoadCodePages; override;
888  public
889  constructor Create;
890 
891  function GetProtocol: string; override;
892  function GetDescription: string; override;
893  end;
894 
895 implementation
896 
897 uses SysUtils, ZPlainLoader, Classes, ZEncoding
898  {$IFDEF WITH_UNITANSISTRINGS}, AnsiStrings{$ENDIF};
899 
900 { TZPostgreSQLBaseDriver }
901 
902 function TZPostgreSQLBaseDriver.GetUnicodeCodePageName: String;
903 begin
904  Result := 'UNICODE';
905 end;
906 
907 procedure TZPostgreSQLBaseDriver.LoadCodePages;
908 begin
909  { MultiByte }
910  AddCodePage('EUC_JP', Ord(csEUC_JP), ceAnsi, zCP_EUC_JP, '', 3); { EUC_JP Japanese EUC }
911  AddCodePage('EUC_CN', Ord(csEUC_CN), ceAnsi, zCP_EUC_CN, '', 3); {EUC_CN Chinese EUC}
912  AddCodePage('EUC_KR', Ord(csEUC_KR), ceAnsi, zCP_euc_kr, '', 3); {Extended UNIX Code-KR Korean}
913  AddCodePage('JOHAB', Ord(csJOHAB), ceAnsi, ZCP_JOHAB, '', 3); {JOHAB Korean (Hangul)}
914  AddCodePage('EUC_TW', Ord(csEUC_TW), ceAnsi, $ffff, '', 3); {Extended UNIX Code-TW Traditional Chinese, Taiwanese}
915  AddCodePage('UNICODE', Ord(csUNICODE_PODBC), ceUTF8, zCP_UTF8, '', 4); {UNICODE Unicode (UTF-8)}
916  AddCodePage('MULE_INTERNAL', Ord(csMULE_INTERNAL), ceAnsi, $ffff, '', 4); { Mule internal code Multilingual Emacs }
917  {SingleByte}
918  AddCodePage('SQL_ASCII', Ord(csSQL_ASCII), ceAnsi, zCP_us_ascii); {unspecified (see text) any}
919  AddCodePage('LATIN1', Ord(csLATIN1), ceAnsi, zCP_WIN1252); { ISO 8859-1, ECMA 94 Western European }
920  AddCodePage('LATIN2', Ord(csLATIN2), ceAnsi, zCP_L2_ISO_8859_2); { ISO 8859-2, ECMA 94 Central European }
921  AddCodePage('LATIN3', Ord(csLATIN3), ceAnsi, zCP_L3_ISO_8859_3); { ISO 8859-3, ECMA 94 South European }
922  AddCodePage('LATIN4', Ord(csLATIN4), ceAnsi, zCP_L4_ISO_8859_4); { ISO 8859-4, ECMA 94 North European }
923  AddCodePage('LATIN5', Ord(csLATIN5), ceAnsi, zCP_L5_ISO_8859_9); { ISO 8859-9, ECMA 128 Turkish }
924  AddCodePage('LATIN6', Ord(csLATIN6), ceAnsi, zCP_L6_ISO_8859_10); { ISO 8859-10, ECMA 144 Nordic }
925  AddCodePage('LATIN7', Ord(csLATIN7), ceAnsi, zCP_L7_ISO_8859_13); { ISO 8859-13 Baltic }
926  AddCodePage('LATIN8', Ord(csLATIN8), ceAnsi, zCP_L8_ISO_8859_14); { ISO 8859-14 Celtic }
927  AddCodePage('LATIN9', Ord(csLATIN9), ceAnsi, zCP_L9_ISO_8859_15); { ISO 8859-15 LATIN1 with Euro and accents }
928  AddCodePage('LATIN10', Ord(csLATIN10), ceAnsi, zCP_L10_ISO_8859_16); { ISO 8859-16, ASRO SR 14111 Romanian }
929  AddCodePage('ISO_8859_5', Ord(csISO_8859_5), ceAnsi, zCP_L5_ISO_8859_5); { ISO 8859-5, ECMA 113 Latin/Cyrillic}
930  AddCodePage('ISO_8859_6', Ord(csISO_8859_6), ceAnsi, zCP_L6_ISO_8859_6); { ISO 8859-6, ECMA 114 Latin/Arabic }
931  AddCodePage('ISO_8859_7', Ord(csISO_8859_7), ceAnsi, zCP_L7_ISO_8859_7); { ISO 8859-7, ECMA 118 Latin/Greek }
932  AddCodePage('ISO_8859_8', Ord(csISO_8859_8), ceAnsi, zCP_L8_ISO_8859_8); { ISO 8859-8, ECMA 121 Latin/Hebrew }
933  AddCodePage('KOI8', Ord(csKOI8), ceAnsi, zCP_KOI8R); { KOI8-R(U) Cyrillic }
934  AddCodePage('WIN', Ord(csWIN), ceAnsi, zCP_WIN1251); { Windows CP1251 }
935  AddCodePage('ALT', Ord(csALT), ceAnsi, zCP_DOS866); { Windows CP866 }
936  AddCodePage('WIN1256', Ord(csWIN1256), ceAnsi, cCP_WIN1256); { Windows CP1256 Arabic }
937  AddCodePage('TCVN', Ord(csTCVN), ceAnsi, zCP_WIN1258); { TCVN-5712/Windows CP1258 (Vietnamese) }
938  AddCodePage('WIN874', Ord(csWIN874), ceAnsi, zCP_DOS874); { Windows CP874 (Thai) }
939 end;
940 
941 procedure TZPostgreSQLBaseDriver.LoadApi;
942 begin
943 { ************** Load adresses of API Functions ************* }
944  with Loader do
945  begin
946  { === in fe-connect.c === }
947  @POSTGRESQL_API.PQconnectdb := GetAddress('PQconnectdb');
948  @POSTGRESQL_API.PQsetdbLogin := GetAddress('PQsetdbLogin');
949  @POSTGRESQL_API.PQconndefaults := GetAddress('PQconndefaults');
950  @POSTGRESQL_API.PQfinish := GetAddress('PQfinish');
951  @POSTGRESQL_API.PQreset := GetAddress('PQreset');
952  @POSTGRESQL_API.PQrequestCancel := GetAddress('PQrequestCancel');
953  @POSTGRESQL_API.PQdb := GetAddress('PQdb');
954  @POSTGRESQL_API.PQuser := GetAddress('PQuser');
955  @POSTGRESQL_API.PQpass := GetAddress('PQpass');
956  @POSTGRESQL_API.PQhost := GetAddress('PQhost');
957  @POSTGRESQL_API.PQport := GetAddress('PQport');
958  @POSTGRESQL_API.PQtty := GetAddress('PQtty');
959  @POSTGRESQL_API.PQoptions := GetAddress('PQoptions');
960  @POSTGRESQL_API.PQstatus := GetAddress('PQstatus');
961  @POSTGRESQL_API.PQserverVersion:= GetAddress('PQserverVersion');
962  @POSTGRESQL_API.PQerrorMessage := GetAddress('PQerrorMessage');
963  @POSTGRESQL_API.PQsocket := GetAddress('PQsocket');
964  @POSTGRESQL_API.PQbackendPID := GetAddress('PQbackendPID');
965  @POSTGRESQL_API.PQtrace := GetAddress('PQtrace');
966  @POSTGRESQL_API.PQuntrace := GetAddress('PQuntrace');
967  @POSTGRESQL_API.PQsetNoticeProcessor := GetAddress('PQsetNoticeProcessor');
968  @POSTGRESQL_API.PQclientEncoding := GetAddress('PQclientEncoding');
969  { === in fe-exec.c === }
970  @POSTGRESQL_API.PQexec := GetAddress('PQexec');
971  @POSTGRESQL_API.PQexecParams := GetAddress('PQexecParams');
972  @POSTGRESQL_API.PQprepare := GetAddress('PQprepare');
973  @POSTGRESQL_API.PQexecPrepared := GetAddress('PQexecPrepared');
974  @POSTGRESQL_API.PQsendQuery := GetAddress('PQsendQuery');
975  @POSTGRESQL_API.PQsendQueryParams:= GetAddress('PQsendQueryParams');
976  @POSTGRESQL_API.PQsendPrepare := GetAddress('PQsendPrepare');
977  @POSTGRESQL_API.PQsendQueryPrepared := GetAddress('PQsendQueryPrepared');
978  @POSTGRESQL_API.PQgetResult := GetAddress('PQgetResult');
979 
980  @POSTGRESQL_API.PQnotifies := GetAddress('PQnotifies');
981  @POSTGRESQL_API.PQfreeNotify := GetAddress('PQfreeNotify');
982  @POSTGRESQL_API.PQisBusy := GetAddress('PQisBusy');
983  @POSTGRESQL_API.PQconsumeInput := GetAddress('PQconsumeInput');
984  @POSTGRESQL_API.PQgetline := GetAddress('PQgetline');
985  @POSTGRESQL_API.PQputline := GetAddress('PQputline');
986  @POSTGRESQL_API.PQgetlineAsync := GetAddress('PQgetlineAsync');
987  @POSTGRESQL_API.PQputnbytes := GetAddress('PQputnbytes');
988  @POSTGRESQL_API.PQendcopy := GetAddress('PQendcopy');
989  @POSTGRESQL_API.PQfn := GetAddress('PQfn');
990  @POSTGRESQL_API.PQresultStatus := GetAddress('PQresultStatus');
991  @POSTGRESQL_API.PQresultErrorMessage := GetAddress('PQresultErrorMessage');
992  @POSTGRESQL_API.PQntuples := GetAddress('PQntuples');
993  @POSTGRESQL_API.PQnfields := GetAddress('PQnfields');
994  @POSTGRESQL_API.PQbinaryTuples := GetAddress('PQbinaryTuples');
995  @POSTGRESQL_API.PQfname := GetAddress('PQfname');
996  @POSTGRESQL_API.PQfnumber := GetAddress('PQfnumber');
997  @POSTGRESQL_API.PQftable := GetAddress('PQftable');
998  @POSTGRESQL_API.PQftablecol := GetAddress('PQftablecol');
999  @POSTGRESQL_API.PQftype := GetAddress('PQftype');
1000  @POSTGRESQL_API.PQfsize := GetAddress('PQfsize');
1001  @POSTGRESQL_API.PQfmod := GetAddress('PQfmod');
1002  @POSTGRESQL_API.PQcmdStatus := GetAddress('PQcmdStatus');
1003  @POSTGRESQL_API.PQoidValue := GetAddress('PQoidValue');
1004  @POSTGRESQL_API.PQoidStatus := GetAddress('PQoidStatus');
1005  @POSTGRESQL_API.PQcmdTuples := GetAddress('PQcmdTuples');
1006  @POSTGRESQL_API.PQgetvalue := GetAddress('PQgetvalue');
1007  @POSTGRESQL_API.PQgetlength := GetAddress('PQgetlength');
1008  @POSTGRESQL_API.PQgetisnull := GetAddress('PQgetisnull');
1009  @POSTGRESQL_API.PQclear := GetAddress('PQclear');
1010  @POSTGRESQL_API.PQmakeEmptyPGresult := GetAddress('PQmakeEmptyPGresult');
1011 
1012  { === in fe-lobj.c === }
1013  @POSTGRESQL_API.lo_open := GetAddress('lo_open');
1014  @POSTGRESQL_API.lo_close := GetAddress('lo_close');
1015  @POSTGRESQL_API.lo_read := GetAddress('lo_read');
1016  @POSTGRESQL_API.lo_write := GetAddress('lo_write');
1017  @POSTGRESQL_API.lo_lseek := GetAddress('lo_lseek');
1018  @POSTGRESQL_API.lo_creat := GetAddress('lo_creat');
1019  @POSTGRESQL_API.lo_tell := GetAddress('lo_tell');
1020  @POSTGRESQL_API.lo_unlink := GetAddress('lo_unlink');
1021  @POSTGRESQL_API.lo_import := GetAddress('lo_import');
1022  @POSTGRESQL_API.lo_export := GetAddress('lo_export');
1023  @POSTGRESQL_API.PQescapeStringConn := GetAddress('PQescapeStringConn'); //since 7.3
1024  @POSTGRESQL_API.PQescapeByteaConn := GetAddress('PQescapeByteaConn'); // postgresql since 7.3
1025  @POSTGRESQL_API.PQFreemem := GetAddress('PQfreemem'); // since postgresql 7.4
1026  @POSTGRESQL_API.PQescapeString := GetAddress('PQescapeString'); // since postgresql 7.4
1027  @POSTGRESQL_API.PQescapeBytea := GetAddress('PQescapeBytea'); // since postgresql 7.4
1028  @POSTGRESQL_API.PQunescapeBytea := GetAddress('PQunescapeBytea'); // since postgresql 8.3
1029  @POSTGRESQL_API.PQescapeLiteral := GetAddress('PQescapeLiteral'); // since postgresql 9.0
1030  @POSTGRESQL_API.PQescapeIdentifier := GetAddress('PQescapeIdentifier'); // since postgresql 9.0
1031 
1032  @POSTGRESQL_API.PQresultErrorField := GetAddress('PQresultErrorField');
1033  @POSTGRESQL_API.PQgetCancel := GetAddress('PQgetCancel');
1034  @POSTGRESQL_API.PQfreeCancel := GetAddress('PQfreeCancel');
1035  @POSTGRESQL_API.PQcancel := GetAddress('PQcancel');
1036  end;
1037 end;
1038 
1039 constructor TZPostgreSQLBaseDriver.Create;
1040 begin
1041  inherited create;
1042  FLoader := TZNativeLibraryLoader.Create([]);
1043  {$IFNDEF STRICT_DLL_LOADING}
1044  {$IFNDEF UNIX}
1045  FLoader.AddLocation(WINDOWS_DLL_LOCATION);
1046  {$ELSE}
1047  FLoader.AddLocation(LINUX_DLL_LOCATION);
1048  {$ENDIF}
1049  {$ENDIF}
1050  LoadCodePages;
1051 end;
1052 
1053 procedure TZPostgreSQLBaseDriver.Clear(Res: PZPostgreSQLResult);
1054 begin
1055  POSTGRESQL_API.PQclear(Res);
1056 end;
1057 
1058 function TZPostgreSQLBaseDriver.CloseLargeObject(
1059  Handle: PZPostgreSQLConnect; Fd: Integer): Integer;
1060 begin
1061  Result := POSTGRESQL_API.lo_close(Handle, Fd);
1062 end;
1063 
1064 function TZPostgreSQLBaseDriver.ConnectDatabase(
1065  ConnInfo: PAnsiChar): PZPostgreSQLConnect;
1066 begin
1067  Result := POSTGRESQL_API.PQconnectdb(ConnInfo);
1068 end;
1069 
1070 function TZPostgreSQLBaseDriver.ConsumeInput(
1071  Handle: PZPostgreSQLConnect): Integer;
1072 begin
1073  Result := POSTGRESQL_API.PQconsumeInput(Handle);
1074 end;
1075 
1076 function TZPostgreSQLBaseDriver.GetCancel(Handle: PZPostgreSQLConnect): PZPostgreSQLCancel;
1077 begin
1078  if Assigned(POSTGRESQL_API.PQgetCancel) then
1079  Result := POSTGRESQL_API.PQgetCancel(Handle)
1080  else
1081  Result := nil;
1082 end;
1083 
1084 procedure TZPostgreSQLBaseDriver.FreeCancel(Canc: PZPostgreSQLCancel);
1085 begin
1086  if Assigned(POSTGRESQL_API.PQfreeCancel) then
1087  POSTGRESQL_API.PQfreeCancel( Canc);
1088 end;
1089 
1090 function TZPostgreSQLBaseDriver.Cancel(Canc: PZPostgreSQLCancel; Buffer: PChar; Length: Integer): Integer;
1091 begin
1092  if Assigned(POSTGRESQL_API.PQcancel) then
1093  Result := POSTGRESQL_API.PQcancel( Canc, Buffer, Length)
1094  else
1095  Result := 0;
1096 end;
1097 
1098 function TZPostgreSQLBaseDriver.CreateLargeObject(
1099  Handle: PZPostgreSQLConnect; Mode: Integer): Oid;
1100 begin
1101  Result := POSTGRESQL_API.lo_creat(Handle, Mode);
1102 end;
1103 
1104 function TZPostgreSQLBaseDriver.DecodeBYTEA(const value: RawByteString;
1105  const Is_bytea_output_hex: Boolean; Handle: PZPostgreSQLConnect): RawByteString;
1106 var
1107  decoded: PAnsiChar;
1108  Ansi: AnsiString;
1109  len: Longword;
1110 begin
1111  if ( Is_bytea_output_hex ) then
1112  begin
1113  Len := (Length(value)-{$IFDEF WITH_UNITANSISTRINGS}AnsiStrings.AnsiPos{$ELSE}Pos{$ENDIF}('x', value)) div 2; //GetLength of binary result
1114  Ansi := AnsiString(Copy(value, {$IFDEF WITH_UNITANSISTRINGS}AnsiStrings.AnsiPos{$ELSE}Pos{$ENDIF}('x', value)+1, Length(value))); //remove the first 'x'sign-byte
1115  SetLength(Result, Len); //Set length of binary-result
1116  HexToBin(PAnsiChar(Ansi), PAnsichar(Result), Len); //convert hex to binary
1117  end
1118  else
1119  if Assigned(POSTGRESQL_API.PQUnescapeBytea) then
1120  begin
1121  decoded := POSTGRESQL_API.PQUnescapeBytea(PAnsiChar(value), @len);
1122  SetLength(result, len);
1123  if (len > 0) then
1124  Move(decoded^, result[1], len);
1125  if Assigned(POSTGRESQL_API.PQFreemem) then
1126  POSTGRESQL_API.PQFreemem(decoded);
1127  end
1128  else
1129  Result := Value;
1130 end;
1131 
1132 function TZPostgreSQLBaseDriver.SupportsEncodeBYTEA: Boolean;
1133 begin
1134  Result := Assigned(POSTGRESQL_API.PQescapeByteaConn) or
1135  Assigned(POSTGRESQL_API.PQescapeBytea);
1136 end;
1137 
1138 function TZPostgreSQLBaseDriver.SupportsDecodeBYTEA(const Handle: PZPostgreSQLConnect): Boolean;
1139 begin
1140  Result := ( POSTGRESQL_API.PQserverVersion(Handle) div 10000 >= 9 ) or
1141  Assigned(POSTGRESQL_API.PQUnescapeBytea);
1142 end;
1143 
1144 function TZPostgreSQLBaseDriver.SupportsStringEscaping(const ClientDependend: Boolean): Boolean;
1145 begin
1146  if ClientDependend then
1147  Result := Assigned(POSTGRESQL_API.PQescapeStringConn)
1148  else
1149  Result := Assigned(POSTGRESQL_API.PQescapeStringConn) or
1150  Assigned(POSTGRESQL_API.PQescapeString);
1151 end;
1152 
1153 function TZPostgreSQLBaseDriver.EncodeBYTEA(const Value: RawByteString;
1154  Handle: PZPostgreSQLConnect; Quoted: Boolean = True): RawByteString;
1155 var
1156  encoded: PAnsiChar;
1157  len: Longword;
1158  leng: cardinal;
1159 begin
1160  if assigned(POSTGRESQL_API.PQescapeByteaConn) or
1161  Assigned(POSTGRESQL_API.PQescapeBytea) then
1162  begin
1163  leng := Length(Value);
1164  if assigned(POSTGRESQL_API.PQescapeByteaConn) then
1165  encoded := POSTGRESQL_API.PQescapeByteaConn(Handle, PAnsiChar(value), leng, @len)
1166  else
1167  encoded := POSTGRESQL_API.PQescapeBytea(PAnsiChar(value),leng,@len);
1168  SetLength(result, len -1); //removes the #0 byte
1169 
1170  {$IFDEF WITH_STRLCOPY_DEPRECATED}AnsiStrings.{$ENDIF}StrLCopy(PAnsiChar(result), encoded, len - 1);
1171 
1172  POSTGRESQL_API.PQFreemem(encoded);
1173  if Quoted then
1174  result := ''''+result+'''';
1175  end
1176  else
1177  Result := Value;
1178 end;
1179 
1180 function TZPostgreSQLBaseDriver.EndCopy( Handle: PZPostgreSQLConnect): Integer;
1181 begin
1182  Result := POSTGRESQL_API.PQendcopy(Handle);
1183 end;
1184 
1185 function TZPostgreSQLBaseDriver.ExecuteFunction(
1186  Handle: PZPostgreSQLConnect; fnid: Integer; result_buf,
1187  result_len: PInteger; result_is_int: Integer; args: PZPostgreSQLArgBlock;
1188  nargs: Integer): PZPostgreSQLResult;
1189 begin
1190  Result := POSTGRESQL_API.PQfn(Handle, fnid, result_buf,
1191  result_len, result_is_int, PPQArgBlock(args), nargs);
1192 end;
1193 
1194 function TZPostgreSQLBaseDriver.ExecuteQuery(
1195  Handle: PZPostgreSQLConnect; Query: PAnsiChar): PZPostgreSQLResult;
1196 begin
1197  Result := POSTGRESQL_API.PQexec(Handle, Query);
1198 end;
1199 
1200 function TZPostgreSQLBaseDriver.ExecParams(Handle: PPGconn; command: PAnsichar;
1201  nParams: Integer; paramTypes: TPQparamTypes; paramValues: TPQparamValues;
1202  paramLengths: TPQparamLengths; paramFormats: TPQparamFormats;
1203  resultFormat: Integer): PPGresult;
1204 begin
1205  if Assigned(POSTGRESQL_API.PQexecParams) then
1206  Result := POSTGRESQL_API.PQexecParams(Handle, command, nParams, paramtypes,
1207  paramValues, paramLengths, paramFormats, resultFormat)
1208  else
1209  Result := nil;
1210 end;
1211 
1212 function TZPostgreSQLBaseDriver.Prepare(Handle: PPGconn; stmtName: PAnsichar;
1213  query: PAnsiChar; nParams: Integer; paramTypes: TPQparamTypes): PPGresult;
1214 begin
1215  if Assigned(POSTGRESQL_API.PQprepare) then
1216  Result := POSTGRESQL_API.PQprepare(Handle, stmtName, query, nParams, paramTypes)
1217  else
1218  Result := nil;
1219 end;
1220 
1221 function TZPostgreSQLBaseDriver.ExecPrepared(Handle: PPGconn; stmtName: PAnsichar;
1222  nParams: Integer; paramValues: TPQparamValues; paramLengths: TPQparamLengths;
1223  paramFormats: TPQparamFormats; resultFormat: Integer): PPGresult;
1224 begin
1225  if Assigned(POSTGRESQL_API.PQexecPrepared) then
1226  Result := POSTGRESQL_API.PQexecPrepared(Handle, stmtName, nParams,
1227  paramValues, paramLengths, paramFormats, resultFormat)
1228  else
1229  Result := nil;
1230 end;
1231 
1232 function TZPostgreSQLBaseDriver.SendQuery(Handle: PZPostgreSQLConnect; Query: PAnsiChar): Integer;
1233 begin
1234  Result := POSTGRESQL_API.PQsendQuery(Handle, Query);
1235 end;
1236 
1237 function TZPostgreSQLBaseDriver.SendQueryParams(Handle: PPGconn; command: PAnsichar;
1238  nParams: Integer; paramTypes: TPQparamTypes; paramValues: TPQparamValues;
1239  paramLengths: TPQparamLengths; paramFormats: TPQparamFormats;
1240  resultFormat: Integer): Integer;
1241 begin
1242  if Assigned(POSTGRESQL_API.PQsendQueryParams) then
1243  Result := POSTGRESQL_API.PQsendQueryParams(Handle, command, nParams,
1244  paramTypes, paramValues, paramLengths, paramFormats, resultFormat)
1245  else
1246  Result := -1;
1247 end;
1248 
1249 function TZPostgreSQLBaseDriver.SendPrepare(Handle: PPGconn; stmtName: PAnsichar;
1250  query: PAnsiChar; nParams: Integer; paramTypes: TPQparamTypes): Integer;
1251 begin
1252  if Assigned(POSTGRESQL_API.PQsendPrepare) then
1253  Result := POSTGRESQL_API.PQsendPrepare(Handle, stmtName, query, nParams,
1254  paramTypes)
1255  else
1256  Result := -1;
1257 end;
1258 
1259 function TZPostgreSQLBaseDriver.SendQueryPrepared(Handle: PPGconn; stmtName: PAnsichar;
1260  nParams: Integer; paramValues: TPQparamValues;
1261  paramLengths: TPQparamLengths; paramFormats: TPQparamFormats;
1262  resultFormat: Integer): Integer;
1263 begin
1264  if Assigned(POSTGRESQL_API.PQsendQueryPrepared) then
1265  Result := POSTGRESQL_API.PQsendQueryPrepared(Handle, stmtName, nParams,
1266  paramValues, paramLengths, paramFormats, resultFormat)
1267  else
1268  Result := -1;
1269 end;
1270 
1271 function TZPostgreSQLBaseDriver.GetResult(Handle: PZPostgreSQLConnect): PZPostgreSQLResult;
1272 begin
1273  Result := POSTGRESQL_API.PQgetResult(Handle);
1274 end;
1275 
1276 function TZPostgreSQLBaseDriver.DescribePrepared(Handle: PPGconn;
1277  const stmt: PAnsiChar): PPGresult;
1278 begin
1279  if Assigned(POSTGRESQL_API.PQdescribePrepared) then
1280  Result := POSTGRESQL_API.PQdescribePrepared(Handle, stmt)
1281  else
1282  Result := nil;
1283 end;
1284 
1285 function TZPostgreSQLBaseDriver.DescribePortal(Handle: PPGconn;
1286  const portal: PAnsiChar): PPGresult;
1287 begin
1288  if Assigned(POSTGRESQL_API.PQdescribePortal) then
1289  Result := POSTGRESQL_API.PQdescribePortal(Handle, portal)
1290  else
1291  Result := nil;
1292 end;
1293 
1294 function TZPostgreSQLBaseDriver.SendDescribePrepared(Handle: PPGconn;
1295  const stmt: PAnsiChar): Integer;
1296 begin
1297  if Assigned(POSTGRESQL_API.PQsendDescribePrepared) then
1298  Result := POSTGRESQL_API.PQsendDescribePrepared(Handle, stmt)
1299  else
1300  Result := -1;
1301 end;
1302 
1303 function TZPostgreSQLBaseDriver.SendDescribePortal(Handle: PPGconn;
1304  const portal: PAnsiChar): Integer;
1305 begin
1306  if Assigned(POSTGRESQL_API.PQsendDescribePortal) then
1307  Result := POSTGRESQL_API.PQsendDescribePortal(Handle, portal)
1308  else
1309  Result := -1;
1310 end;
1311 
1312 function TZPostgreSQLBaseDriver.ExportLargeObject(
1313  Handle: PZPostgreSQLConnect; ObjId: Oid; FileName: PAnsiChar): Integer;
1314 begin
1315  Result := POSTGRESQL_API.lo_export(Handle, ObjId, FileName);
1316 end;
1317 
1318 procedure TZPostgreSQLBaseDriver.Finish(Handle: PZPostgreSQLConnect);
1319 begin
1320  POSTGRESQL_API.PQfinish(Handle);
1321 end;
1322 
1323 procedure TZPostgreSQLBaseDriver.FreeNotify(Handle: PZPostgreSQLNotify);
1324 begin
1325  POSTGRESQL_API.PQfreeNotify(PPGnotify(Handle));
1326 end;
1327 
1328 function TZPostgreSQLBaseDriver.GetBackendPID(
1329  Handle: PZPostgreSQLConnect): Integer;
1330 begin
1331  Result := POSTGRESQL_API.PQbackendPID(Handle);
1332 end;
1333 
1334 function TZPostgreSQLBaseDriver.GetBinaryTuples(
1335  Res: PZPostgreSQLResult): Integer;
1336 begin
1337  Result := POSTGRESQL_API.PQbinaryTuples(Res);
1338 end;
1339 
1340 function TZPostgreSQLBaseDriver.GetCommandStatus(
1341  Res: PZPostgreSQLResult): PAnsiChar;
1342 begin
1343  Result := POSTGRESQL_API.PQcmdStatus(Res);
1344 end;
1345 
1346 function TZPostgreSQLBaseDriver.GetCommandTuples(
1347  Res: PZPostgreSQLResult): PAnsiChar;
1348 begin
1349  Result := POSTGRESQL_API.PQcmdTuples(Res);
1350 end;
1351 
1352 function TZPostgreSQLBaseDriver.GetConnectDefaults:
1353  PZPostgreSQLConnectInfoOption;
1354 begin
1355  Result := PZPostgreSQLConnectInfoOption(POSTGRESQL_API.PQconndefaults);
1356 end;
1357 
1358 function TZPostgreSQLBaseDriver.GetDatabase(
1359  Handle: PZPostgreSQLConnect): PAnsiChar;
1360 begin
1361  Result := POSTGRESQL_API.PQdb(Handle);
1362 end;
1363 
1364 function TZPostgreSQLBaseDriver.GetErrorMessage(
1365  Handle: PZPostgreSQLConnect): PAnsiChar;
1366 begin
1367  Result := POSTGRESQL_API.PQerrorMessage(Handle);
1368 end;
1369 
1370 function TZPostgreSQLBaseDriver.GetFieldCount(
1371  Res: PZPostgreSQLResult): Integer;
1372 begin
1373  Result := POSTGRESQL_API.PQnfields(Res);
1374 end;
1375 
1376 function TZPostgreSQLBaseDriver.GetFieldMode(Res: PZPostgreSQLResult;
1377  FieldNum: Integer): Integer;
1378 begin
1379  Result := POSTGRESQL_API.PQfmod(Res, FieldNum);
1380 end;
1381 
1382 function TZPostgreSQLBaseDriver.GetFieldName(Res: PZPostgreSQLResult;
1383  FieldNum: Integer): PAnsiChar;
1384 begin
1385  Result := POSTGRESQL_API.PQfname(Res, FieldNum);
1386 end;
1387 
1388 function TZPostgreSQLBaseDriver.GetFieldNumber(
1389  Res: PZPostgreSQLResult; FieldName: PAnsiChar): Integer;
1390 begin
1391  Result := POSTGRESQL_API.PQfnumber(Res, FieldName);
1392 end;
1393 
1394 function TZPostgreSQLBaseDriver.GetFieldTableOID(Res: PZPostgreSQLResult; FieldNum: Integer) : Oid;
1395 begin
1396  Result := POSTGRESQL_API.PQftable(Res, FieldNum);
1397 end;
1398 
1399 function TZPostgreSQLBaseDriver.GetFieldTableColIdx(Res: PZPostgreSQLResult; FieldNum: Integer) : Integer;
1400 begin
1401  Result := POSTGRESQL_API.PQftablecol(Res, FieldNum);
1402 end;
1403 
1404 function TZPostgreSQLBaseDriver.GetFieldSize(Res: PZPostgreSQLResult;
1405  FieldNum: Integer): Integer;
1406 begin
1407  Result := POSTGRESQL_API.PQfsize(Res, FieldNum);
1408 end;
1409 
1410 function TZPostgreSQLBaseDriver.GetFieldType(Res: PZPostgreSQLResult;
1411  FieldNum: Integer): Oid;
1412 begin
1413  Result := POSTGRESQL_API.PQftype(Res, FieldNum);
1414 end;
1415 
1416 function TZPostgreSQLBaseDriver.GetHost(
1417  Handle: PZPostgreSQLConnect): PAnsiChar;
1418 begin
1419  Result := POSTGRESQL_API.PQhost(Handle);
1420 end;
1421 
1422 function TZPostgreSQLBaseDriver.GetIsNull(Res: PZPostgreSQLResult;
1423  TupNum, FieldNum: Integer): Integer;
1424 begin
1425  Result := POSTGRESQL_API.PQgetisnull(Res, TupNum, FieldNum);
1426 end;
1427 
1428 function TZPostgreSQLBaseDriver.GetLength(Res: PZPostgreSQLResult;
1429  TupNum, FieldNum: Integer): Integer;
1430 begin
1431  Result := POSTGRESQL_API.PQgetlength(Res, TupNum, FieldNum);
1432 end;
1433 
1434 function TZPostgreSQLBaseDriver.GetLine(Handle: PZPostgreSQLConnect;
1435  Buffer: PAnsiChar; Length: Integer): Integer;
1436 begin
1437  Result := POSTGRESQL_API.PQgetline(Handle, Buffer, Length);
1438 end;
1439 
1440 function TZPostgreSQLBaseDriver.GetLineAsync(
1441  Handle: PZPostgreSQLConnect; Buffer: PAnsiChar; Length: Integer): Integer;
1442 begin
1443  Result := POSTGRESQL_API.PQgetlineAsync(Handle, Buffer, Length);
1444 end;
1445 
1446 function TZPostgreSQLBaseDriver.GetOidStatus(
1447  Res: PZPostgreSQLResult): PAnsiChar;
1448 begin
1449  Result := POSTGRESQL_API.PQoidStatus(Res);
1450 end;
1451 
1452 function TZPostgreSQLBaseDriver.GetOidValue(
1453  Res: PZPostgreSQLResult): Oid;
1454 begin
1455  Result := POSTGRESQL_API.PQoidValue(Res);
1456 end;
1457 
1458 function TZPostgreSQLBaseDriver.GetOptions(
1459  Handle: PZPostgreSQLConnect): PAnsiChar;
1460 begin
1461  Result := POSTGRESQL_API.PQoptions(Handle);
1462 end;
1463 
1464 function TZPostgreSQLBaseDriver.GetPassword(
1465  Handle: PZPostgreSQLConnect): PAnsiChar;
1466 begin
1467  Result := POSTGRESQL_API.PQpass(Handle);
1468 end;
1469 
1470 function TZPostgreSQLBaseDriver.GetPort(
1471  Handle: PZPostgreSQLConnect): PAnsiChar;
1472 begin
1473  Result := POSTGRESQL_API.PQport(Handle);
1474 end;
1475 
1476 function TZPostgreSQLBaseDriver.GetResultErrorField(Res: PZPostgreSQLResult; FieldCode: TZPostgreSQLFieldCode): PAnsiChar;
1477 begin
1478  if Assigned(POSTGRESQL_API.PQresultErrorField) then
1479  Result := POSTGRESQL_API.PQresultErrorField(Res, ord(FieldCode))
1480  else
1481  Result := '';
1482 end;
1483 
1484 
1485 function TZPostgreSQLBaseDriver.GetResultErrorMessage(
1486  Res: PZPostgreSQLResult): PAnsiChar;
1487 begin
1488  Result := POSTGRESQL_API.PQresultErrorMessage(Res);
1489 end;
1490 
1491 function TZPostgreSQLBaseDriver.GetResultStatus(
1492  Res: PZPostgreSQLResult): TZPostgreSQLExecStatusType;
1493 begin
1494  Result := TZPostgreSQLExecStatusType(POSTGRESQL_API.PQresultStatus(Res));
1495 end;
1496 
1497 function TZPostgreSQLBaseDriver.GetRowCount(
1498  Res: PZPostgreSQLResult): Integer;
1499 begin
1500  Result := POSTGRESQL_API.PQntuples(Res);
1501 end;
1502 
1503 function TZPostgreSQLBaseDriver.GetSocket(
1504  Handle: PZPostgreSQLConnect): Integer;
1505 begin
1506  Result := POSTGRESQL_API.PQsocket(Handle);
1507 end;
1508 
1509 function TZPostgreSQLBaseDriver.GetStandardConformingStrings: Boolean;
1510 begin
1511  Result := False;
1512 end;
1513 
1514 function TZPostgreSQLBaseDriver.GetStatus(
1515  Handle: PZPostgreSQLConnect): TZPostgreSQLConnectStatusType;
1516 begin
1517  Result := TZPostgreSQLConnectStatusType(POSTGRESQL_API.PQstatus(Handle));
1518 end;
1519 
1520 function TZPostgreSQLBaseDriver.GetClientEncoding(Handle: PPGconn): Integer; //EgonHugeist
1521 begin
1522  Result := POSTGRESQL_API.PQclientEncoding(Handle);
1523 end;
1524 
1525 function TZPostgreSQLBaseDriver.GetTTY(
1526  Handle: PZPostgreSQLConnect): PAnsiChar;
1527 begin
1528  Result := POSTGRESQL_API.PQtty(Handle);
1529 end;
1530 
1531 function TZPostgreSQLBaseDriver.GetUser(
1532  Handle: PZPostgreSQLConnect): PAnsiChar;
1533 begin
1534  Result := POSTGRESQL_API.PQuser(Handle);
1535 end;
1536 
1537 function TZPostgreSQLBaseDriver.GetValue(Res: PZPostgreSQLResult;
1538  TupNum, FieldNum: Integer): PAnsiChar;
1539 begin
1540  Result := POSTGRESQL_API.PQgetvalue(Res, TupNum, FieldNum);
1541 end;
1542 
1543 function TZPostgreSQLBaseDriver.ImportLargeObject(
1544  Handle: PZPostgreSQLConnect; FileName: PAnsiChar): Oid;
1545 begin
1546  Result := POSTGRESQL_API.lo_import(Handle, FileName);
1547 end;
1548 
1549 function TZPostgreSQLBaseDriver.IsBusy(
1550  Handle: PZPostgreSQLConnect): Integer;
1551 begin
1552  Result := POSTGRESQL_API.PQisBusy(Handle);
1553 end;
1554 
1555 function TZPostgreSQLBaseDriver.MakeEmptyResult(
1556  Handle: PZPostgreSQLConnect;
1557  Status: TZPostgreSQLExecStatusType): PZPostgreSQLResult;
1558 begin
1559  Result := POSTGRESQL_API.PQmakeEmptyPGresult(Handle,
1560  TZPostgreSQLExecStatusType(Status));
1561 end;
1562 
1563 function TZPostgreSQLBaseDriver.Notifies(
1564  Handle: PZPostgreSQLConnect): PZPostgreSQLNotify;
1565 begin
1566  Result := PZPostgreSQLNotify(POSTGRESQL_API.PQnotifies(Handle));
1567 end;
1568 
1569 function TZPostgreSQLBaseDriver.OpenLargeObject(
1570  Handle: PZPostgreSQLConnect; ObjId: Oid; Mode: Integer): Integer;
1571 begin
1572  Result := POSTGRESQL_API.lo_open(Handle, ObjId, Mode);
1573 end;
1574 
1575 function TZPostgreSQLBaseDriver.PutBytes(Handle: PZPostgreSQLConnect;
1576  Buffer: PAnsiChar; Length: Integer): Integer;
1577 begin
1578  Result := POSTGRESQL_API.PQputnbytes(Handle, Buffer, Length);
1579 end;
1580 
1581 function TZPostgreSQLBaseDriver.PutLine(Handle: PZPostgreSQLConnect;
1582  Buffer: PAnsiChar): Integer;
1583 begin
1584  Result := POSTGRESQL_API.PQputline(Handle, Buffer);
1585 end;
1586 
1587 function TZPostgreSQLBaseDriver.ReadLargeObject(
1588  Handle: PZPostgreSQLConnect; Fd: Integer; Buffer: PAnsiChar;
1589  Length: Integer): Integer;
1590 begin
1591  Result := POSTGRESQL_API.lo_read(Handle, Fd, Buffer, Length);
1592 end;
1593 
1594 function TZPostgreSQLBaseDriver.RequestCancel(
1595  Handle: PZPostgreSQLConnect): Integer;
1596 begin
1597  Result := POSTGRESQL_API.PQrequestCancel(Handle);
1598 end;
1599 
1600 procedure TZPostgreSQLBaseDriver.Reset(Handle: PZPostgreSQLConnect);
1601 begin
1602  POSTGRESQL_API.PQreset(Handle);
1603 end;
1604 
1605 function TZPostgreSQLBaseDriver.SeekLargeObject(
1606  Handle: PZPostgreSQLConnect; Fd, Offset, Whence: Integer): Integer;
1607 begin
1608  Result := POSTGRESQL_API.lo_lseek(Handle, Fd, Offset, Whence);
1609 end;
1610 
1611 function TZPostgreSQLBaseDriver.SetDatabaseLogin(Host, Port, Options,
1612  TTY, Db, User, Passwd: PAnsiChar): PZPostgreSQLConnect;
1613 begin
1614  Result := POSTGRESQL_API.PQsetdbLogin(Host, Port, Options, TTY, Db,
1615  User, Passwd);
1616 end;
1617 
1618 procedure TZPostgreSQLBaseDriver.SetNoticeProcessor(
1619  Handle: PZPostgreSQLConnect; Proc: TZPostgreSQLNoticeProcessor;
1620  Arg: Pointer);
1621 begin
1622  POSTGRESQL_API.PQsetNoticeProcessor(Handle, Proc, Arg);
1623 end;
1624 
1625 function TZPostgreSQLBaseDriver.TellLargeObject(
1626  Handle: PZPostgreSQLConnect; Fd: Integer): Integer;
1627 begin
1628  Result := POSTGRESQL_API.lo_tell(Handle, Fd);
1629 end;
1630 
1631 procedure TZPostgreSQLBaseDriver.Trace(Handle: PZPostgreSQLConnect;
1632  DebugPort: Pointer);
1633 begin
1634  POSTGRESQL_API.PQtrace(Handle, DebugPort);
1635 end;
1636 
1637 function TZPostgreSQLBaseDriver.UnlinkLargeObject(
1638  Handle: PZPostgreSQLConnect; ObjId: Oid): Integer;
1639 begin
1640  Result := POSTGRESQL_API.lo_unlink(Handle, ObjId);
1641 end;
1642 
1643 procedure TZPostgreSQLBaseDriver.Untrace(Handle: PZPostgreSQLConnect);
1644 begin
1645  POSTGRESQL_API.PQuntrace(Handle);
1646 end;
1647 
1648 function TZPostgreSQLBaseDriver.WriteLargeObject(
1649  Handle: PZPostgreSQLConnect; Fd: Integer; Buffer: PAnsiChar;
1650  Length: Integer): Integer;
1651 begin
1652  Result := POSTGRESQL_API.lo_write(Handle, Fd, Buffer, Length);
1653 end;
1654 
1655 function TZPostgreSQLBaseDriver.GetPlainFunc():PAPI;
1656 begin
1657  result:= @POSTGRESQL_API;
1658 end;
1659 
1660 function TZPostgreSQLBaseDriver.EscapeString(Handle: Pointer; const Value: RawByteString;
1661  ConSettings: PZConSettings; WasEncoded: Boolean = False): RawByteString;
1662 var
1663  ResLen: NativeUInt;
1664  Temp: PAnsiChar;
1665  SourceTemp: RawByteString;
1666  IError: Integer;
1667 begin
1668  if ( Assigned(POSTGRESQL_API.PQescapeStringConn) or
1669  Assigned(POSTGRESQL_API.PQescapeString) ) and ( Value <> '' )then
1670  begin
1671  IError := 0;
1672  {$IFDEF UNICODE}
1673  SourceTemp := Value;
1674  {$ELSE}
1675  if WasEncoded then
1676  SourceTemp := Value
1677  else
1678  SourceTemp := ZPlainString(Value, ConSettings); //check encoding too
1679  {$ENDIF}
1680  GetMem(Temp, Length(SourceTemp)*2);
1681  if Assigned(POSTGRESQL_API.PQescapeStringConn) then
1682  ResLen := POSTGRESQL_API.PQescapeStringConn(Handle, Temp,
1683 
1684 
1685  PAnsiChar(SourceTemp), {$IFDEF WITH_STRLEN_DEPRECATED}AnsiStrings.{$ENDIF}StrLen(PAnsiChar(SourceTemp)), @IError)
1686  else
1687  ResLen := POSTGRESQL_API.PQescapeString(Temp, PAnsiChar(SourceTemp),
1688  {$IFDEF WITH_STRLEN_DEPRECATED}AnsiStrings.{$ENDIF}StrLen(PAnsiChar(SourceTemp)));
1689  if not (IError = 0) then
1690  raise Exception.Create('Wrong escape behavior!');
1691  SetLength(Result, ResLen);
1692  Move(Temp^, PAnsiChar(Result)^, ResLen);
1693  FreeMem(Temp);
1694  end
1695  else
1696  Result := Value;
1697  Result := #39+Result+#39;
1698 end;
1699 
1700 { TZPostgreSQL7PlainDriver }
1701 
1702 function TZPostgreSQL7PlainDriver.Clone: IZPlainDriver;
1703 begin
1704  Result := TZPostgreSQL7PlainDriver.Create;
1705 end;
1706 
1707 constructor TZPostgreSQL7PlainDriver.Create;
1708 begin
1709  inherited Create;
1710  {$IFNDEF UNIX}
1711  FLoader.AddLocation(WINDOWS_DLL7_LOCATION);
1712  {$ENDIF}
1713 end;
1714 
1715 function TZPostgreSQL7PlainDriver.GetProtocol: string;
1716 begin
1717  Result := 'postgresql-7';
1718 end;
1719 
1720 function TZPostgreSQL7PlainDriver.GetDescription: string;
1721 begin
1722  Result := 'Native Plain Driver for PostgreSQL 7.x';
1723 end;
1724 
1725 { TZPostgreSQL8PlainDriver }
1726 function TZPostgreSQL8PlainDriver.Clone: IZPlainDriver;
1727 begin
1728  Result := TZPostgreSQL8PlainDriver.Create;
1729 end;
1730 
1731 function TZPostgreSQL8PlainDriver.GetUnicodeCodePageName: String;
1732 begin
1733  Result := 'UTF8';
1734 end;
1735 
1736 procedure TZPostgreSQL8PlainDriver.LoadCodePages;
1737 begin
1738  inherited LoadCodePages;
1739  { Version 8.1 }
1740  {MultiByte}
1741  ResetCodePage(Ord(csUNICODE_PODBC), 'UTF8', Ord(csUTF8), ceUTF8, zCP_UTF8, '', 4); { Unicode, 8-bit all }
1742  AddCodePage('BIG5', Ord(csBIG5), ceAnsi, zCP_Big5, '', 2); { Big Five Traditional Chinese }
1743  AddCodePage('GB18030', Ord(csGB18030), ceAnsi, zCP_GB18030, '', 2); { National Standard Chinese }
1744  AddCodePage('GBK', Ord(csGBK), ceAnsi, zCP_GB2312, '', 2); { Extended National Standard Simplified Chinese }
1745  AddCodePage('SJIS', Ord(csSJIS), ceAnsi, zCP_SHIFTJS, '', 2); { Shift JIS Japanese }
1746  AddCodePage('UHC', Ord(csUHC), ceAnsi, zCP_EUCKR, '', 2); { Unified Hangul Code Korean }
1747  {SingleByte}
1748  ResetCodePage(Ord(csALT), 'WIN866', Ord(csWIN866), ceAnsi, zCP_DOS866); { Windows CP866 Cyrillic } //No longer in use
1749  AddCodePage('WIN874', Ord(csWIN874), ceAnsi, zCP_DOS874); { Windows CP874 Thai }
1750  AddCodePage('WIN1250', Ord(csWIN1250), ceAnsi, zCP_WIN1250); { Windows CP1250 Central European }
1751  ResetCodePage(Ord(csWIN), 'WIN1251', Ord(csWIN1251), ceAnsi, zCP_WIN1251); { Windows CP1251 Cyrillic } //No longer in use
1752  AddCodePage('WIN1252', Ord(csWIN1252), ceAnsi, zCP_WIN1252); { Windows CP1252 Western European }
1753  ResetCodePage(Ord(csTCVN), 'WIN1258', Ord(csWIN1258),ceAnsi, zCP_WIN1258); { Windows CP1258 Vietnamese } //No longer in use
1754 
1755  { Version 8.3 }
1756  {MultiByte}
1757  AddCodePage('EUC_JIS_2004', Ord(csEUC_JIS_2004), ceAnsi, $ffff, '', 3); { Extended UNIX Code-JP, JIS X 0213 Japanese }
1758  AddCodePage('SHIFT_JIS_2004', Ord(csSHIFT_JIS_2004), ceAnsi, zCP_SHIFTJS, '', 3); { Shift JIS, JIS X 0213 Japanese }
1759  {SingleChar}
1760  AddCodePage('WIN1253', Ord(csWIN1253), ceAnsi, zCP_WIN1253); { Windows CP1253 Greek }
1761  AddCodePage('WIN1254', Ord(csWIN1254), ceAnsi, zCP_WIN1254); { Windows CP1254 Turkish }
1762  AddCodePage('WIN1255', Ord(csWIN1255), ceAnsi, zCP_WIN1255); { Windows CP1255 Hebrew }
1763  AddCodePage('WIN1257', Ord(csWIN1257), ceAnsi, zCP_WIN1257); { Windows CP1257 Baltic }
1764 
1765  { Version 8.4 }
1766  {SingleChar}
1767  AddCodePage('KOI8U', Ord(csKOI8U), ceAnsi, zCP_KOI8U); { KOI8-U Cyrillic (Ukrainian) }
1768 end;
1769 
1770 constructor TZPostgreSQL8PlainDriver.Create;
1771 begin
1772  inherited Create;
1773  {$IFNDEF UNIX}
1774  FLoader.AddLocation(WINDOWS_DLL8_LOCATION);
1775  {$ELSE}
1776  FLoader.AddLocation(LINUX_DLL82_LOCATION);
1777  FLoader.AddLocation(LINUX_DLL8_LOCATION);
1778  {$ENDIF}
1779 end;
1780 
1781 function TZPostgreSQL8PlainDriver.GetProtocol: string;
1782 begin
1783  Result := 'postgresql-8';
1784 end;
1785 
1786 function TZPostgreSQL8PlainDriver.GetDescription: string;
1787 begin
1788  Result := 'Native Plain Driver for PostgreSQL 8.x';
1789 end;
1790 
1791 { TZPostgreSQL9PlainDriver }
1792 function TZPostgreSQL9PlainDriver.Clone: IZPlainDriver;
1793 begin
1794  Result := TZPostgreSQL9PlainDriver.Create;
1795 end;
1796 
1797 procedure TZPostgreSQL9PlainDriver.LoadCodePages;
1798 begin
1799  inherited LoadCodePages;
1800  ResetCodePage(Ord(csKOI8), 'KOI8R', Ord(csKOI8R)); { KOI8-R Cyrillic (Russian) } //No longer in use
1801 end;
1802 
1803 constructor TZPostgreSQL9PlainDriver.Create;
1804 begin
1805  inherited Create;
1806  Self.FLoader.ClearLocations;
1807  {$IFNDEF STRICT_DLL_LOADING}
1808  {$IFNDEF UNIX}
1809  FLoader.AddLocation(WINDOWS_DLL_LOCATION);
1810  {$ELSE}
1811  FLoader.AddLocation(LINUX_DLL_LOCATION);
1812  {$ENDIF}
1813  {$ENDIF}
1814 end;
1815 
1816 function TZPostgreSQL9PlainDriver.GetProtocol: string;
1817 begin
1818  Result := 'postgresql-9';
1819 end;
1820 
1821 function TZPostgreSQL9PlainDriver.GetDescription: string;
1822 begin
1823  Result := 'Native Plain Driver for PostgreSQL 9.x';
1824 end;
1825 
1826 function TZPostgreSQL9PlainDriver.GetStandardConformingStrings: Boolean;
1827 begin
1828  Result := True;
1829 end;
1830 
1831 end.
1832