pg.ddx.io pgsql-interfaces@postgresql.org mailing list archive
help / color / mirror / Atom feed From: James Loh <jamesloh@neways.com.my>
To: pgsql-interfaces@postgresql.org
Cc: howe@carcass.dhs.org
Subject: Postgresql unit
Date: Thu, 31 May 2001 23:06:34 +0800
Message-ID: <5.0.2.1.0.20010531230236.01c29700@neways.com.my> (raw )
I have successfully converted the Postgresql unit in Zeos to Kylix. There
needs to be more testing. So, I am emailling to to this mailing list in the
hope that more people will use it and also help get Zeos fully converted to
the Kylix platform.
Attached is the unit.
Attachments:
ZLibPgSql.pas (text/plain, 16.1K) download
{********************************************************}
{ }
{ Zeos Database Objects }
{ Plain interface to libpq.dll }
{ }
{ Copyright (c) 1999-2001 Sergey Seroukhov }
{ }
{********************************************************}
unit ZLibPgSql;
interface
uses {$IFNDEF LINUX}Windows,{$ELSE} Libc, {$ENDIF} Classes, ZSqlTypes;
{$IFNDEF LINUX}
{$INCLUDE ..\Zeos.inc}
{$ELSE}
{$INCLUDE ../Zeos.inc}
{$ENDIF}
{***************** Plain API Constants definition ****************}
const
{$IFNDEF LINUX}
DEFAULT_DLL_LOCATION = 'libpq.dll';
{$ELSE}
DEFAULT_DLL_LOCATION = 'libpq.so';
{$ENDIF}
{ Type Lengths }
NAMEDATALEN = 32;
{ OIDNAMELEN should be set to NAMEDATALEN + sizeof(Oid) }
OIDNAMELEN = 36;
INV_WRITE = $00020000;
INV_READ = $00040000;
SEEK_SET = 0;
SEEK_CUR = 1;
SEEK_END = 2;
{****************** Plain API Types definition *****************}
type
Oid = Integer;
{ Application-visible enum types }
ConnStatusType = (
CONNECTION_OK,
CONNECTION_BAD
);
ExecStatusType = (
PGRES_EMPTY_QUERY,
PGRES_COMMAND_OK, { a query command that doesn't return anything
was executed properly by the backend }
PGRES_TUPLES_OK, { a query command that returns tuples
was executed properly by the backend,
PGresult contains the result tuples }
PGRES_COPY_OUT, { Copy Out data transfer in progress }
PGRES_COPY_IN, { Copy In data transfer in progress }
PGRES_BAD_RESPONSE, { an unexpected response was recv'd from
the backend }
PGRES_NONFATAL_ERROR,
PGRES_FATAL_ERROR
);
{ String descriptions of the ExecStatusTypes }
pgresStatus = array[$00..$ff] of PChar;
{ PGconn encapsulates a connection to the backend.
The contents of this struct are not supposed to be known to applications.
}
PGconn = Pointer;
PPGconn = Pointer;
{ PGresult encapsulates the result of a query (or more precisely, of a single
SQL command --- a query string given to PQsendQuery can contain multiple
commands and thus return multiple PGresult objects).
The contents of this struct are not supposed to be known to applications.
}
PGresult = Pointer;
PPGresult = Pointer;
{ PGnotify represents the occurrence of a NOTIFY message.
Ideally this would be an opaque typedef, but it's so simple that it's
unlikely to change.
NOTE: in Postgres 6.4 and later, the be_pid is the notifying backend's,
whereas in earlier versions it was always your own backend's PID.
}
PGnotify = packed record
relname: array [0..NAMEDATALEN-1] of Char; { name of relation containing data }
be_pid: Integer; { process id of backend }
end;
PPGnotify = ^PGnotify;
{ PQnoticeProcessor is the function type for the notice-message callback. }
PQnoticeProcessor = procedure(arg: Pointer; message: PChar); cdecl;
{ Print options for PQprint() }
{
We can't use the conventional "bool", because we are designed to be
included in a user's program, and user may already have that type
defined. Pqbool, on the other hand, is unlikely to be used.
}
PPChar = array[00..$ff] of PChar;
PQprintOpt = packed record
header: TBool; { print output field headings and row count }
align: TBool; { fill align the fields }
standard: TBool; { old brain dead format }
html3: TBool; { output html tables }
expanded: TBool; { expand tables }
pager: TBool; { use pager for output if needed }
fieldSep: PChar; { field separator }
tableOpt: PChar; { insert to HTML <table ...> }
caption: PChar; { HTML <caption> }
fieldName: PPChar; { null terminated array of repalcement field names }
end;
PPQprintOpt = ^PQprintOpt;
{ ----------------
Structure for the conninfo parameter definitions returned by PQconndefaults
----------------
}
PQconninfoOption = packed record
keyword: PChar; { The keyword of the option }
envvar: PChar; { Fallback environment variable name }
compiled: PChar; { Fallback compiled in default value }
val: PChar; { Options value }
lab: PChar; { Label for field in connect dialog }
dispchar: PChar; { Character to display for this field
in a connect dialog. Values are:
"" Display entered value as is
"*" Password field - hide value
"D" Debug options - don't
create a field by default }
dispsize: Integer; { Field size in characters for dialog }
end;
PPQConninfoOption = ^PQconninfoOption;
{ ----------------
PQArgBlock -- structure for PQfn() arguments
----------------
}
PQArgBlock = packed record
len: Integer;
isint: Integer;
case u: Boolean of
True: (ptr: PInteger); { can't use void (dec compiler barfs) }
False: (_int: Integer);
end;
PPQArgBlock = ^PQArgBlock;
{************** Plain API Function types definition *************}
{ === in fe-connect.c === }
TPQconnectdb = function(ConnInfo: PChar): PPGconn; cdecl;
TPQsetdbLogin = function(Host, Port, Options, Tty, Db, User, Passwd: PChar): PPGconn; cdecl;
TPQconndefaults = function: PPQconninfoOption; cdecl;
TPQfinish = procedure(Handle: PPGconn); cdecl;
TPQreset = procedure(Handle: PPGconn); cdecl;
TPQrequestCancel = function(Handle: PPGconn): Integer; cdecl;
TPQdb = function(Handle: PPGconn): PChar; cdecl;
TPQuser = function(Handle: PPGconn): PChar; cdecl;
TPQpass = function(Handle: PPGconn): PChar; cdecl;
TPQhost = function(Handle: PPGconn): PChar; cdecl;
TPQport = function(Handle: PPGconn): PChar; cdecl;
TPQtty = function(Handle: PPGconn): PChar; cdecl;
TPQoptions = function(Handle: PPGconn): PChar; cdecl;
TPQstatus = function(Handle: PPGconn): ConnStatusType; cdecl;
TPQerrorMessage = function(Handle: PPGconn): PChar; cdecl;
TPQsocket = function(Handle: PPGconn): Integer; cdecl;
TPQbackendPID = function(Handle: PPGconn): Integer; cdecl;
TPQtrace = procedure(Handle: PPGconn; DebugPort: Pointer); cdecl;
TPQuntrace = procedure(Handle: PPGconn); cdecl;
TPQsetNoticeProcessor = procedure(Handle: PPGconn; Proc: PQnoticeProcessor; Arg: Pointer); cdecl;
{ === in fe-exec.c === }
TPQexec = function(Handle: PPGconn; Query: PChar): PPGresult; cdecl;
TPQnotifies = function(Handle: PPGconn): PPGnotify; cdecl;
TPQnotifyFree = procedure(Handle: PPGnotify);cdecl;
TPQsendQuery = function(Handle: PPGconn; Query: PChar): Integer; cdecl;
TPQgetResult = function(Handle: PPGconn): PPGresult; cdecl;
TPQisBusy = function(Handle: PPGconn): Integer; cdecl;
TPQconsumeInput = function(Handle: PPGconn): Integer; cdecl;
TPQgetline = function(Handle: PPGconn; Str: PChar; length: Integer): Integer; cdecl;
TPQputline = function(Handle: PPGconn; Str: PChar): Integer; cdecl;
TPQgetlineAsync = function(Handle: PPGconn; Buffer: PChar; BufSize: Integer): Integer; cdecl;
TPQputnbytes = function(Handle: PPGconn; Buffer: PChar; NBytes: Integer): Integer; cdecl;
TPQendcopy = function(Handle: PPGconn): Integer; cdecl;
TPQfn = function(Handle: PPGconn; fnid: Integer; result_buf, result_len: PInteger; result_is_int: Integer; args: PPQArgBlock; nargs: Integer): PPGresult; cdecl;
TPQresultStatus = function(Result: PPGresult): ExecStatusType; cdecl;
TPQresultErrorMessage = function(Result: PPGresult): PChar; cdecl;
TPQntuples = function(Result: PPGresult): Integer; cdecl;
TPQnfields = function(Result: PPGresult): Integer; cdecl;
TPQbinaryTuples = function(Result: PPGresult): Integer; cdecl;
TPQfname = function(Result: PPGresult; field_num: Integer): PChar; cdecl;
TPQfnumber = function(Result: PPGresult; field_name: PChar): Integer; cdecl;
TPQftype = function(Result: PPGresult; field_num: Integer): Oid; cdecl;
TPQfsize = function(Result: PPGresult; field_num: Integer): Integer; cdecl;
TPQfmod = function(Result: PPGresult; field_num: Integer): Integer; cdecl;
TPQcmdStatus = function(Result: PPGresult): PChar; cdecl;
TPQoidValue = function(Result: PPGresult): Oid; cdecl;
TPQoidStatus = function(Result: PPGresult): PChar; cdecl;
TPQcmdTuples = function(Result: PPGresult): PChar; cdecl;
TPQgetvalue = function(Result: PPGresult; tup_num, field_num: Integer): PChar; cdecl;
TPQgetlength = function(Result: PPGresult; tup_num, field_num: Integer): Integer; cdecl;
TPQgetisnull = function(Result: PPGresult; tup_num, field_num: Integer): Integer; cdecl;
TPQclear = procedure(Result: PPGresult); cdecl;
TPQmakeEmptyPGresult = function(Handle: PPGconn; status: ExecStatusType): PPGresult; cdecl;
{ === in fe-lobj.c === }
Tlo_open = function(Handle: PPGconn; lobjId: Oid; mode: Integer): Integer; cdecl;
Tlo_close = function(Handle: PPGconn; fd: Integer): Integer; cdecl;
Tlo_read = function(Handle: PPGconn; fd: Integer; buf: PChar; len: Integer): Integer; cdecl;
Tlo_write = function(Handle: PPGconn; fd: Integer; buf: PChar; len: Integer): Integer; cdecl;
Tlo_lseek = function(Handle: PPGconn; fd, offset, whence: Integer): Integer; cdecl;
Tlo_creat = function(Handle: PPGconn; mode: Integer): Oid; cdecl;
Tlo_tell = function(Handle: PPGconn; fd: Integer): Integer; cdecl;
Tlo_unlink = function(Handle: PPGconn; lobjId: Oid): Integer; cdecl;
Tlo_import = function(Handle: PPGconn; filename: PChar): Oid; cdecl;
Tlo_export = function(Handle: PPGconn; lobjId: Oid; filename: PChar): Integer; cdecl;
{************* Plain API Function variables definition ************}
var
{ === in fe-connect.c === }
PQconnectdb: TPQconnectdb;
PQsetdbLogin: TPQsetdbLogin;
PQconndefaults: TPQconndefaults;
PQfinish: TPQfinish;
PQreset: TPQreset;
PQrequestCancel: TPQrequestCancel;
PQdb: TPQdb;
PQuser: TPQuser;
PQpass: TPQpass;
PQhost: TPQhost;
PQport: TPQport;
PQtty: TPQtty;
PQoptions: TPQoptions;
PQstatus: TPQstatus;
PQerrorMessage: TPQerrorMessage;
PQsocket: TPQsocket;
PQbackendPID: TPQbackendPID;
PQtrace: TPQtrace;
PQuntrace: TPQuntrace;
PQsetNoticeProcessor: TPQsetNoticeProcessor;
{ === in fe-exec.c === }
PQexec: TPQexec;
PQnotifies: TPQnotifies;
PQnotifyFree: TPQnotifyFree;
PQsendQuery: TPQsendQuery;
PQgetResult: TPQgetResult;
PQisBusy: TPQisBusy;
PQconsumeInput: TPQconsumeInput;
PQgetline: TPQgetline;
PQputline: TPQputline;
PQgetlineAsync: TPQgetlineAsync;
PQputnbytes: TPQputnbytes;
PQendcopy: TPQendcopy;
PQfn: TPQfn;
PQresultStatus: TPQresultStatus;
PQresultErrorMessage: TPQresultErrorMessage;
PQntuples: TPQntuples;
PQnfields: TPQnfields;
PQbinaryTuples: TPQbinaryTuples;
PQfname: TPQfname;
PQfnumber: TPQfnumber;
PQftype: TPQftype;
PQfsize: TPQfsize;
PQfmod: TPQfmod;
PQcmdStatus: TPQcmdStatus;
PQoidValue: TPQoidValue;
PQoidStatus: TPQoidStatus;
PQcmdTuples: TPQcmdTuples;
PQgetvalue: TPQgetvalue;
PQgetlength: TPQgetlength;
PQgetisnull: TPQgetisnull;
PQclear: TPQclear;
PQmakeEmptyPGresult: TPQmakeEmptyPGresult;
{ === in fe-lobj.c === }
lo_open: Tlo_open;
lo_close: Tlo_close;
lo_read: Tlo_read;
lo_write: Tlo_write;
lo_lseek: Tlo_lseek;
lo_creat: Tlo_creat;
lo_tell: Tlo_tell;
lo_unlink: Tlo_unlink;
lo_import: Tlo_import;
lo_export: Tlo_export;
function PgSqlLoadLib: Boolean;
const
DLL: string = DEFAULT_DLL_LOCATION;
{$IFNDEF LINUX}
hDLL: THandle = 0;
{$ELSE}
hDLL: Pointer = nil;
{$ENDIF}
implementation
uses SysUtils, ZDBaseConst;
function TryGetProcAddr(ProcName: PChar): Pointer;
begin
{$IFDEF LINUX}
Result := dlsym(hDLL, ProcName);
if Result = nil then
{$ELSE}
Result := GetProcAddress(hDLL, ProcName);
if not Assigned(Result) then
{$ENDIF}
raise Exception.Create(ProcName + ' not found');
end;
{ Initialize PostgreSQL dynamic library }
function PgSqlLoadLib: Boolean;
begin
{$IFDEF LINUX}
if hDLL = nil then
hDLL := dlopen(PChar(DLL), RTLD_GLOBAL);
if hDLL <> nil then
{$ELSE}
if hDLL = 0 then
hDLL := LoadLibrary(PChar(DLL));
if hDLL <> 0 then
{$ENDIF}
begin
{ === in fe-connect.c === }
@PQconnectdb := TryGetProcAddr('PQconnectdb');
@PQsetdbLogin := TryGetProcAddr('PQsetdbLogin');
@PQconndefaults := TryGetProcAddr('PQconndefaults');
@PQfinish := TryGetProcAddr('PQfinish');
@PQreset := TryGetProcAddr('PQreset');
@PQrequestCancel := TryGetProcAddr('PQrequestCancel');
@PQdb := TryGetProcAddr('PQdb');
@PQuser := TryGetProcAddr('PQuser');
@PQpass := TryGetProcAddr('PQpass');
@PQhost := TryGetProcAddr('PQhost');
@PQport := TryGetProcAddr('PQport');
@PQtty := TryGetProcAddr('PQtty');
@PQoptions := TryGetProcAddr('PQoptions');
@PQstatus := TryGetProcAddr('PQstatus');
@PQerrorMessage := TryGetProcAddr('PQerrorMessage');
@PQsocket := TryGetProcAddr('PQsocket');
@PQbackendPID := TryGetProcAddr('PQbackendPID');
@PQtrace := TryGetProcAddr('PQtrace');
@PQuntrace := TryGetProcAddr('PQuntrace');
@PQsetNoticeProcessor := TryGetProcAddr('PQsetNoticeProcessor');
{ === in fe-exec.c === }
@PQexec := TryGetProcAddr('PQexec');
@PQnotifies := TryGetProcAddr('PQnotifies');
{$IFNDEF LINUX}
@PQnotifyFree := TryGetProcAddr('PQnotifyFree');
{$ENDIF}
@PQsendQuery := TryGetProcAddr('PQsendQuery');
@PQgetResult := TryGetProcAddr('PQgetResult');
@PQisBusy := TryGetProcAddr('PQisBusy');
@PQconsumeInput := TryGetProcAddr('PQconsumeInput');
@PQgetline := TryGetProcAddr('PQgetline');
@PQputline := TryGetProcAddr('PQputline');
@PQgetlineAsync := TryGetProcAddr('PQgetlineAsync');
@PQputnbytes := TryGetProcAddr('PQputnbytes');
@PQendcopy := TryGetProcAddr('PQendcopy');
@PQfn := TryGetProcAddr('PQfn');
@PQresultStatus := TryGetProcAddr('PQresultStatus');
@PQresultErrorMessage := TryGetProcAddr('PQresultErrorMessage');
@PQntuples := TryGetProcAddr('PQntuples');
@PQnfields := TryGetProcAddr('PQnfields');
@PQbinaryTuples := TryGetProcAddr('PQbinaryTuples');
@PQfname := TryGetProcAddr('PQfname');
@PQfnumber := TryGetProcAddr('PQfnumber');
@PQftype := TryGetProcAddr('PQftype');
@PQfsize := TryGetProcAddr('PQfsize');
@PQfmod := TryGetProcAddr('PQfmod');
@PQcmdStatus := TryGetProcAddr('PQcmdStatus');
@PQoidValue := TryGetProcAddr('PQoidValue');
@PQoidStatus := TryGetProcAddr('PQoidStatus');
@PQcmdTuples := TryGetProcAddr('PQcmdTuples');
@PQgetvalue := TryGetProcAddr('PQgetvalue');
@PQgetlength := TryGetProcAddr('PQgetlength');
@PQgetisnull := TryGetProcAddr('PQgetisnull');
@PQclear := TryGetProcAddr('PQclear');
@PQmakeEmptyPGresult := TryGetProcAddr('PQmakeEmptyPGresult');
{ === in fe-lobj.c === }
@lo_open := TryGetProcAddr('lo_open');
@lo_close := TryGetProcAddr('lo_close');
@lo_read := TryGetProcAddr('lo_read');
@lo_write := TryGetProcAddr('lo_write');
@lo_lseek := TryGetProcAddr('lo_lseek');
@lo_creat := TryGetProcAddr('lo_creat');
@lo_tell := TryGetProcAddr('lo_tell');
@lo_unlink := TryGetProcAddr('lo_unlink');
@lo_import := TryGetProcAddr('lo_import');
@lo_export := TryGetProcAddr('lo_export');
Result := True;
end else
raise Exception.Create(Format(SLibraryNotFound,[DLL]));
end;
initialization
finalization
{$IFDEF LINUX}
if hDLL <> nil then
dlclose(hDLL);
hDLL := nil;
{$ELSE}
if hDLL <> 0 then
FreeLibrary(hDLL);
{$ENDIF}
end.
view thread (3+ messages) latest in thread
Message-ID: <5.0.2.1.0.20010531230236.01c29700@neways.com.my>
Permalink: ../5.0.2.1.0.20010531230236.01c29700@neways.com.my/
Also on: postgresql.org/message-id/5.0.2.1.0.20010531230236.01c29700@neways.com.my
copy link · copy postgr.es
reply Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: pgsql-interfaces@postgresql.org
Cc: jamesloh@neways.com.my, howe@carcass.dhs.org
Subject: Re: Postgresql unit
In-Reply-To: <5.0.2.1.0.20010531230236.01c29700@neways.com.my>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox