{*********************************************************}
{ }
{ Zeos Database Objects }
{ Delphi plain driver interface to DBLibrary }
{ }
{ Originally written by Janos Fegyverneki }
{ FreeTDS supportd by Bogdan Dragulin }
{ }
{*********************************************************}
{@********************************************************}
{ Copyright (c) 1999-2020 Zeos Development Group }
{ }
{ License Agreement: }
{ }
{ This library is distributed in the hope that it will be }
{ useful, but WITHOUT ANY WARRANTY; without even the }
{ implied warranty of MERCHANTABILITY or FITNESS FOR }
{ A PARTICULAR PURPOSE. See the GNU Lesser General }
{ Public License for more details. }
{ }
{ The source code of the ZEOS Libraries and packages are }
{ distributed under the Library GNU General Public }
{ License (see the file COPYING / COPYING.ZEOS) }
{ with the following modification: }
{ As a special exception, the copyright holders of this }
{ library give you permission to link this library with }
{ independent modules to produce an executable, }
{ regardless of the license terms of these independent }
{ modules, and to copy and distribute the resulting }
{ executable under terms of your choice, provided that }
{ you also meet, for each linked independent module, }
{ the terms and conditions of the license of that module. }
{ An independent module is a module which is not derived }
{ from or based on this library. If you modify this }
{ library, you may extend this exception to your version }
{ of the library, but you are not obligated to do so. }
{ If you do not wish to do so, delete this exception }
{ statement from your version. }
{ }
{ }
{ The project web site is located on: }
{ https://zeoslib.sourceforge.io/ (FORUM) }
{ http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}
{ svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN) }
{ }
{ http://www.sourceforge.net/projects/zeoslib. }
{ }
{ }
{ Zeos Development Group. }
{********************************************************@}
unit ZPlainDbLibDriver;
interface
{$I ZPlain.inc}
{$IFNDEF ZEOS_DISABLE_DBLIB}
uses Classes, {$IFDEF FPC}syncobjs{$ELSE}SyncObjs{$ENDIF},
ZCompatibility, ZPlainDriver, ZClasses;
{***************** Plain API Constants definition ****************}
const
{ General #define }
TIMEOUT_IGNORE = Cardinal(-1);
TIMEOUT_INFINITE = 0;
TIMEOUT_MAXIMUM = 1200*1000; { 20 minutes maximum timeout value in ms}
{ Used for ServerType in dbgetprocinfo }
SERVTYPE_UNKNOWN = 0;
SERVTYPE_MICROSOFT = 1;
{ Used by dbcolinfo }
{enum CI_TYPES }
CI_REGULAR = 1;
CI_ALTERNATE = 2;
CI_CURSOR = 3;
{ Bulk Copy Definitions (bcp) }
DB_IN = 1; { Transfer from client to server }
DB_OUT = 2; { Transfer from server to client }
BCPMAXERRS = 1; { bcp_control parameter }
BCPFIRST = 2; { bcp_control parameter }
BCPLAST = 3; { bcp_control parameter }
BCPBATCH = 4; { bcp_control parameter }
BCPKEEPNULLS = 5; { bcp_control parameter }
BCPABORT = 6; { bcp_control parameter }
BCPKEEPIDENTITY = 8; { bcp_control parameter }
BCPLABELED = 5; { bcp_control parameter }
BCPHINTS = 6; { bcp_control parameter }
DBCMDNONE = 0; { bcp_control parameter }
DBCMDPEND = 1; { bcp_control parameter }
DBCMDSENT = 2; { bcp_control parameter }
TINYBIND = 1;
SMALLBIND = 2;
INTBIND = 3;
CHARBIND = 4;
BINARYBIND = 5;
BITBIND = 6;
DATETIMEBIND = 7;
MONEYBIND = 8;
FLT8BIND = 9;
STRINGBIND = 10;
NTBSTRINGBIND = 11;
VARYCHARBIND = 12;
VARYBINBIND = 13;
FLT4BIND = 14;
SMALLMONEYBIND = 15;
SMALLDATETIBIND = 16;
DECIMALBIND = 17;
NUMERICBIND = 18;
SRCDECIMALBIND = 19;
SRCNUMERICBIND = 20;
MAXBIND = SRCNUMERICBIND;
DBSAVE = 1;
DBNOSAVE = 0;
DBNOERR = -1;
DBFAIL = 0;
DBSUCCEED = 1;
DBFINDONE = $04; { Definately done }
DBMORE = $10; { Maybe more commands waiting }
DBMORE_ROWS = $20; { This command returned rows }
MAXNAME = 31;
DBTXTSLEN = 8; { Timestamp length }
DBTXPLEN = 16; { Text pointer length }
{ Error code returns }
INT_EXIT = 0;
INT_CONTINUE = 1;
INT_CANCEL = 2;
//from FreeTDS sybdb.h:
{ DBVERSION_xxx are used with dbsetlversion() }
DBVERSION_100= 2; // Sybase TDS 5.0
DBVERSION_42 = 3; // This can be used for old Microsoft and Sybase servers
DBVERSION_70 = 4;
DBVERSION_71 = 5;
DBVERSION_72 = 6;
DBVERSION_73 = 7;
{Zeos dbsetversion placeholders}
ZVersion_UNKNOWN = 0;
ZVersion_2_0 = 1; { pre 4.0 SQL Server }
ZVersion_3_4 = 2; { Microsoft SQL Server (3.0) }
ZVersion_4_0 = 3; { 4.0 SQL Server }
ZVersion_4_2 = 4; { 4.2 SQL Server }
ZVersion_4_6 = 5; { 2.0 OpenServer and 4.6 SQL Server. }
ZVersion_4_9_5 = 6; { 4.9.5 (NCR) SQL Server }
ZVersion_5_0 = 7; { 5.0 SQL Server }
ZVersion_7_0 = 8; { Microsoft SQL Server 7.0 }
ZVersion_8_0 = 9; { Microsoft SQL Server 2000 }
ZVersion_9_0 = 10; { Microsoft SQL Server 2005 }
ZVersion_7_1 = 9; { Microsoft SQL Server 2000 }
ZVersion_7_2 = 10; { Microsoft SQL Server 2005 }
ZVersion_7_3 = 11; { Microsoft SQL Server 2008 }
ZVersionMax = 13; { known count of available versions }
ZVersionEmpty = -1; { placeholder for unsuported version }
{ DB-Library datatypes }
const
{Zeos DBOption placeholders}
{ a large list of options, DBTEXTSIZE is needed by sybtcl }
Z_PARSEONLY = 0;
Z_ESTIMATE = 1;
Z_SHOWPLAN = 2;
Z_NOEXEC = 3;
Z_ARITHIGNORE = 4;
Z_NOCOUNT = 5;
Z_ARITHABORT = 6;
Z_TEXTLIMIT = 7;
Z_BROWSE = 8;
Z_OFFSET = 9;
Z_STAT = 10;
Z_ERRLVL = 11;
Z_CONFIRM = 12;
Z_STORPROCID = 13;
Z_BUFFER = 14;
Z_NOAUTOFREE = 15;
Z_ROWCOUNT = 16;
Z_TEXTSIZE = 17;
Z_NATLANG = 18;
Z_DATEFORMAT = 19;
Z_PRPAD = 20;
Z_PRCOLSEP = 21;
Z_PRLINELEN = 22;
Z_PRLINESEP = 23;
Z_LFCONVERT = 24;
Z_DATEFIRST = 25;
Z_CHAINXACTS = 26;
Z_FIPSFLAG = 27;
Z_ISOLATION = 28;
Z_AUTH = 29;
Z_IDENTITY = 30;
Z_NOIDCOL = 31;
Z_DATESHORT = 32;
Z_CLIENTCURSORS = 33;
Z_SETTIME = 34;
Z_QUOTEDIDENT = 35;
Z_NUMOPTIONS = 36;
Z_PADOFF = 37;
Z_PADON = 38;
Z_OFF = 39;
Z_ON = 40;
Z_NOSUCHOPTION = 41;
Z_MAXOPTTEXT = 42;
Z_ANSITOOEM = 43;
Z_OEMTOANSI = 44;
type TdbOption = ({Zeos DBOption placeholders}
{ a large list of options, DBTEXTSIZE is needed by sybtcl }
dboptPARSEONLY = 0,
dboptESTIMATE = 1,
dboptSHOWPLAN = 2,
dboptNOEXEC = 3,
dboptARITHIGNORE = 4,
dboptNOCOUNT = 5,
dboptARITHABORT = 6,
dboptTEXTLIMIT = 7,
dboptBROWSE = 8,
dboptOFFSET = 9,
dboptSTAT = 10,
dboptERRLVL = 11,
dboptCONFIRM = 12,
dboptSTORPROCID = 13,
dboptBUFFER = 14,
dboptNOAUTOFREE = 15,
dboptROWCOUNT = 16,
dboptTEXTSIZE = 17,
dboptNATLANG = 18,
dboptDATEFORMAT = 19,
dboptPRPAD = 20,
dboptPRCOLSEP = 21,
dboptPRLINELEN = 22,
dboptPRLINESEP = 23,
dboptLFCONVERT = 24,
dboptDATEFIRST = 25,
dboptCHAINXACTS = 26,
dboptFIPSFLAG = 27,
dboptISOLATION = 28,
dboptAUTH = 29,
dboptIDENTITY = 30,
dboptNOIDCOL = 31,
dboptDATESHORT = 32,
dboptCLIENTCURSORS = 33,
dboptSETTIME = 34,
dboptQUOTEDIDENT = 35,
dboptANSITOOEM = 36,
dboptOEMTOANSI = 37
);
const
{ loginrec manipulation Placeholders}
Z_SETHOST = 0;
Z_SETUSER = 1;
Z_SETPWD = 2;
Z_SETHID = 3;
Z_SETAPP = 4;
Z_SETBCP = 5;
Z_SETSECURE = 6;
Z_SETLANG = 7;
Z_SETNOSHORT = 8;
Z_SETHIER = 9;
Z_SETCHARSET = 10;
Z_SETPACKET = 11;
Z_SETENCRYPT = 12;
Z_SETLABELED = 13;
Z_SETDBNAME = 14;
Z_SETLOGINTIME = 15;
Z_SETFALLBACK = 16;
{ DBLib options }
const
DBLIBDBBUFFER = 0;
DBLIBDBOFFSET = 1;
DBLIBDBROWCOUNT = 2;
DBLIBDBSTAT = 3;
DBLIBDBTEXTLIMIT = 4;
DBLIBDBTEXTSIZE = 5;
DBLIBDBARITHABORT = 6;
DBLIBDBARITHIGNORE = 7;
DBLIBDBNOAUTOFREE = 8;
DBLIBDBNOCOUNT = 9;
DBLIBDBNOEXEC = 10;
DBLIBDBPARSEONLY = 11;
DBLIBDBSHOWPLAN = 12;
DBLIBDBSTORPROCID = 13;
DBLIBDBANSITOOEM = 14;
DBLIBDBOEMTOANSI = 15;
DBLIBDBCLIENTCURSORS = 16;
DBLIBDBSET_TIME = 17;
DBLIBDBQUOTEDIDENT = 18;
{ FreeTDS options, a large list of options, DBTEXTSIZE is needed by sybtcl }
TDSPARSEONLY = 0;
TDSESTIMATE = 1;
TDSSHOWPLAN = 2;
TDSNOEXEC = 3;
TDSARITHIGNORE = 4;
TDSNOCOUNT = 5;
TDSARITHABORT = 6;
TDSTEXTLIMIT = 7;
TDSBROWSE = 8;
TDSOFFSET = 9;
TDSSTAT = 10;
TDSERRLVL = 11;
TDSCONFIRM = 12;
TDSSTORPROCID = 13;
TDSBUFFER = 14;
TDSNOAUTOFREE = 15;
TDSROWCOUNT = 16;
TDSTEXTSIZE = 17;
TDSNATLANG = 18;
TDSDATEFORMAT = 19;
TDSPRPAD = 20;
TDSPRCOLSEP = 21;
TDSPRLINELEN = 22;
TDSPRLINESEP = 23;
TDSLFCONVERT = 24;
TDSDATEFIRST = 25;
TDSCHAINXACTS = 26;
TDSFIPSFLAG = 27;
TDSISOLATION = 28;
TDSAUTH = 29;
TDSIDENTITY = 30;
TDSNOIDCOL = 31;
TDSDATESHORT = 32;
TDSCLIENTCURSORS = 33;
TDSSETTIME = 34;
TDSQUOTEDIDENT = 35;
TDSNUMOPTIONS = 36;
TDSPADOFF = 0;
TDSPADON = 1;
TDSOFF = 0;
TDSON = 1;
NOSUCHOPTION = 2;
MAXOPTTEXT = 32;
{ common Login manipulations }
DBSETHOST = 1;
DBSETUSER = 2;
DBSETPWD = 3;
{ Sybase Login manipulations }
const
SYBDBSETHOST = DBSETHOST;
SYBDBSETUSER = DBSETUSER;
SYBDBSETPWD = DBSETPWD;
SYBDBSETHID = 4;
SYBDBSETAPP = 5;
SYBDBSETBCP = 6;
SYBDBSETLANG = 7;
SYBDBSETNOSHORT = 8;
SYBDBSETHIER = 9;
SYBDBSETCHARSET = 10;
SYBDBSETPACKET = 11;
SYBDBSETENCRYPT = 12;
SYBDBSETLABELED = 13;
{ MsSQL Login manipulations }
const
MSDBSETHOST = DBSETHOST;
MSDBSETUSER = DBSETUSER;
MSDBSETPWD = DBSETPWD;
MSDBSETAPP = 4;
MSDBSETID = 5;
MSDBSETLANG = 6;
MSDBSETSECURE = 7;
MSDBSET_LOGIN_TIME = 10;
MSDBSETFALLBACK = 12;
{TDS Loginrec manipulations}
TDSDBSETHOST = DBSETHOST;
TDSDBSETUSER = DBSETUSER;
TDSDBSETPWD = DBSETPWD;
TDSDBSETHID = 4;
TDSDBSETAPP = 5;
TDSDBSETBCP = 6;
TDSDBSETSECURE = 6;
TDSDBSETLANG = 7;
TDSDBSETNOSHORT = 8;
TDSDBSETHIER = 9;
TDSDBSETCHARSET = 10;
TDSDBSETPACKET = 11;
TDSDBSETENCRYPT = 12;
TDSDBSETLABELED = 13;
TDSDBSETDBNAME = 14;
{ TDS_DBVERSION_xxx are used with dbsetversion() }
TDSDBVERSION_UNKNOWN = 0;
TDSDBVERSION_46 = 1; // Sybase <= 10
TDSDBVERSION_100 = 2; // Sybase TDS 5.0 Ver >= 10
TDSDBVERSION_42 = 3; // This can be used for old Microsoft(<=6.5)
TDSDBVERSION_70 = 4; // MSSQL v7..2000
TDSDBVERSION_71 = 5;
TDSDBVERSION_80 = TDSDBVERSION_71;
TDSDBVERSION_72 = 6; //MSSQL >= 2005... ?
TDSDBVERSION_73 = 7;
{ these two are defined by Microsoft for dbsetlname() }
DBVER42 = 8;
DBVER60 = 9;
(**
* DBTDS_xxx are returned by DBTDS()
* The integer values of the constants are poorly chosen.
*)
DBTDS_UNKNOWN = 0;
DBTDS_2_0 = 1; { pre 4.0 SQL Server }
DBTDS_3_4 = 2; { Microsoft SQL Server (3.0) }
DBTDS_4_0 = 3; { 4.0 SQL Server }
DBTDS_4_2 = 4; { 4.2 SQL Server }
DBTDS_4_6 = 5; { 2.0 OpenServer and 4.6 SQL Server. }
DBTDS_4_9_5 = 6; { 4.9.5 (NCR) SQL Server }
DBTDS_5_0 = 7; { 5.0 SQL Server }
DBTDS_7_0 = 8; { Microsoft SQL Server 7.0 }
DBTDS_8_0 = 9; { Microsoft SQL Server 2000 }
DBTDS_9_0 = 10; { Microsoft SQL Server 2005 }
DBTDS_7_1 = 9; { Microsoft SQL Server 2000 }
DBTDS_7_2 = 10; { Microsoft SQL Server 2005 }
DBTDS_7_3 = 11; { Microsoft SQL Server 2008 }
{ Data stream tokens }
SQLCOLFMT = $a1;
OLD_SQLCOLFMT = $2a;
SQLPROCID = $7c;
SQLCOLNAME = $a0;
SQLTABNAME = $a4;
SQLCOLINFO = $a5;
SQLALTNAME = $a7;
SQLALTFMT = $a8;
SQLERROR = $aa;
SQLINFO = $ab;
SQLRETURNVALUE = $ac;
SQLRETURNSTATUS = $79;
SQLRETURN = $db;
SQLCONTROL = $ae;
SQLALTCONTROL = $af;
SQLROW = $d1;
SQLALTROW = $d3;
SQLDONE = $fd;
SQLDONEPROC = $fe;
SQLDONEINPROC = $ff;
SQLOFFSET = $78;
SQLORDER = $a9;
SQLLOGINACK = $ad; { NOTICE: change to real value }
{ Ag op tokens }
SQLAOPCNT = $4b;
SQLAOPSUM = $4d;
SQLAOPAVG = $4f;
SQLAOPMIN = $51;
SQLAOPMAX = $52;
SQLAOPANY = $53;
SQLAOPNOOP = $56;
{ Error numbers (dberrs) DB-Library error codes }
SQLEMEM = 10000;
SQLENULL = 10001;
SQLENLOG = 10002;
SQLEPWD = 10003;
SQLECONN = 10004;
SQLEDDNE = 10005;
SQLENULLO = 10006;
SQLESMSG = 10007;
SQLEBTOK = 10008;
SQLENSPE = 10009;
SQLEREAD = 10010;
SQLECNOR = 10011;
SQLETSIT = 10012;
SQLEPARM = 10013;
SQLEAUTN = 10014;
SQLECOFL = 10015;
SQLERDCN = 10016;
SQLEICN = 10017;
SQLECLOS = 10018;
SQLENTXT = 10019;
SQLEDNTI = 10020;
SQLETMTD = 10021;
SQLEASEC = 10022;
SQLENTLL = 10023;
SQLETIME = 10024;
SQLEWRIT = 10025;
SQLEMODE = 10026;
SQLEOOB = 10027;
SQLEITIM = 10028;
SQLEDBPS = 10029;
SQLEIOPT = 10030;
SQLEASNL = 10031;
SQLEASUL = 10032;
SQLENPRM = 10033;
SQLEDBOP = 10034;
SQLENSIP = 10035;
SQLECNULL = 10036;
SQLESEOF = 10037;
SQLERPND = 10038;
SQLECSYN = 10039;
SQLENONET = 10040;
SQLEBTYP = 10041;
SQLEABNC = 10042;
SQLEABMT = 10043;
SQLEABNP = 10044;
SQLEBNCR = 10045;
SQLEAAMT = 10046;
SQLENXID = 10047;
SQLEIFNB = 10048;
SQLEKBCO = 10049;
SQLEBBCI = 10050;
SQLEKBCI = 10051;
SQLEBCWE = 10052;
SQLEBCNN = 10053;
SQLEBCOR = 10054;
SQLEBCPI = 10055;
SQLEBCPN = 10056;
SQLEBCPB = 10057;
SQLEVDPT = 10058;
SQLEBIVI = 10059;
SQLEBCBC = 10060;
SQLEBCFO = 10061;
SQLEBCVH = 10062;
SQLEBCUO = 10063;
SQLEBUOE = 10064;
SQLEBWEF = 10065;
SQLEBTMT = 10066;
SQLEBEOF = 10067;
SQLEBCSI = 10068;
SQLEPNUL = 10069;
SQLEBSKERR = 10070;
SQLEBDIO = 10071;
SQLEBCNT = 10072;
SQLEMDBP = 10073;
SQLINIT = 10074;
SQLCRSINV = 10075;
SQLCRSCMD = 10076;
SQLCRSNOIND = 10077;
SQLCRSDIS = 10078;
SQLCRSAGR = 10079;
SQLCRSORD = 10080;
SQLCRSMEM = 10081;
SQLCRSBSKEY = 10082;
SQLCRSNORES = 10083;
SQLCRSVIEW = 10084;
SQLCRSBUFR = 10085;
SQLCRSFROWN = 10086;
SQLCRSBROL = 10087;
SQLCRSFRAND = 10088;
SQLCRSFLAST = 10089;
SQLCRSRO = 10090;
SQLCRSTAB = 10091;
SQLCRSUPDTAB = 10092;
SQLCRSUPDNB = 10093;
SQLCRSVIIND = 10094;
SQLCRSNOUPD = 10095;
SQLCRSOS2 = 10096;
SQLEBCSA = 10097;
SQLEBCRO = 10098;
SQLEBCNE = 10099;
SQLEBCSK = 10100;
SQLEUVBF = 10101;
SQLEBIHC = 10102;
SQLEBWFF = 10103;
SQLNUMVAL = 10104;
SQLEOLDVR = 10105;
SQLEBCPS = 10106;
SQLEDTC = 10107;
SQLENOTIMPL = 10108;
SQLENONFLOAT = 10109;
SQLECONNFB = 10110;
{ The severity levels are defined here }
EXINFO = 1; { Informational, non-error }
EXUSER = 2; { User error }
EXNONFATAL = 3; { Non-fatal error }
EXCONVERSION = 4; { Error in DB-LIBRARY data conversion }
EXSERVER = 5; { The Server has returned an error flag }
EXTIME = 6; { We have exceeded our timeout period while }
{ waiting for a response from the Server - the }
{ DBPROCESS is still alive }
EXPROGRAM = 7; { Coding error in user program }
EXRESOURCE = 8; { Running out of resources - the DBPROCESS may be dead }
EXCOMM = 9; { Failure in communication with Server - the DBPROCESS is dead }
EXFATAL = 10; { Fatal error - the DBPROCESS is dead }
EXCONSISTENCY = 11; { Internal software error - notify MS Technical Support }
{ Offset identifiers }
OFF_SELECT = $16d;
OFF_FROM = $14f;
OFF_ORDER = $165;
OFF_COMPUTE = $139;
OFF_TABLE = $173;
OFF_PROCEDURE = $16a;
OFF_STATEMENT = $1cb;
OFF_PARAM = $1c4;
OFF_EXEC = $12c;
{ Decimal constants }
MAXNUMERICLEN = 16;
MAXNUMERICDIG = 38;
DEFAULTPRECISION = 18;
DEFAULTSCALE = 0;
{ DB-Table constants}
{ Pack the following structures on a word boundary }
TDSMAXTABLENAME = 512;
TDSMAXCOLNAMELEN = 512;
{ DB-Table constants}
{ Pack the following structures on a word boundary }
MAXTABLENAME = 30;
MAXCOLNAMELEN= 30;
{ DB-Library datatype definitions }
DBMAXCHAR=256; // Max length of DBVARBINARY and DBVARCHAR, etc.
{ Print lengths for certain fixed length data types }
PRINT4 = 11;
PRINT2 = 6;
PRINT1 = 3;
PRFLT8 = 20;
PRMONEY = 26;
PRBIT = 3;
PRDATETIME = 27;
PRDECIMAL = (MAXNUMERICDIG + 2);
PRNUMERIC = (MAXNUMERICDIG + 2);
SUCCEED = 1;
FAIL = 0;
SUCCEED_ABORT = 2;
DBUNKNOWN = 2; { FALSE = 0, TRUE = 1 }
MORE_ROWS = -1;
NO_MORE_ROWS = -2;
REG_ROW = MORE_ROWS;
BUF_FULL = -3; { only if buffering is turned on }
{ Status code for dbresults(). Possible return values are }
{ SUCCEED, FAIL, and NO_MORE_RESULTS. }
NO_MORE_RESULTS = 2;
NO_MORE_RPC_RESULTS = 3;
{ Standard exit and error values }
STDEXIT = 0;
ERREXIT = -1;
{ dbrpcinit flags }
DBRPCRECOMPILE = $0001;
DBRPCRESET = $0004;
DBRPCCURSOR = $0008;
{ dbrpcparam flags }
DBRPCRETURN = $1;
DBRPCDEFAULT = $2;
{ Cursor related constants }
{ Following flags are used in the concuropt parameter in the dbcursoropen function }
CUR_READONLY = 1; { Read only cursor, no data modifications }
CUR_LOCKCC = 2; { Intent to update, all fetched data locked when }
{ dbcursorfetch is called inside a transaction block }
CUR_OPTCC = 3; { Optimistic concurrency control, data modifications }
{ succeed only if the row hasn't been updated since }
{ the last fetch. }
CUR_OPTCCVAL = 4; { Optimistic concurrency control based on selected column values }
{ Following flags are used in the scrollopt parameter in dbcursoropen }
CUR_FORWARD = 0; { Forward only scrolling }
CUR_KEYSET = -1; { Keyset driven scrolling }
CUR_DYNAMIC = 1; { Fully dynamic }
CUR_INSENSITIVE = -2; { Server-side cursors only }
{ Following flags define the fetchtype in the dbcursorfetch function }
FETCH_FIRST = 1; { Fetch first n rows }
FETCH_NEXT = 2; { Fetch next n rows }
FETCH_PREV = 3; { Fetch previous n rows }
FETCH_RANDOM = 4; { Fetch n rows beginning with given row # }
FETCH_RELATIVE = 5; { Fetch relative to previous fetch row # }
FETCH_LAST = 6; { Fetch the last n rows }
{ Following flags define the per row status as filled by dbcursorfetch and/or dbcursorfetchex }
FTC_EMPTY = $00; { No row available }
FTC_SUCCEED = $01; { Fetch succeeded, (failed if not set) }
FTC_MISSING = $02; { The row is missing }
FTC_ENDOFKEYSET = $04; { End of the keyset reached }
FTC_ENDOFRESULTS = $08; { End of results set reached }
{ Following flags define the operator types for the dbcursor function }
CRS_UPDATE = 1; { Update operation }
CRS_DELETE = 2; { Delete operation }
CRS_INSERT = 3; { Insert operation }
CRS_REFRESH = 4; { Refetch given row }
CRS_LOCKCC = 5; { Lock given row }
{ Following value can be passed to the dbcursorbind function for NOBIND type }
NOBIND = -2; { Return length and pointer to data }
{ Following are values used by DBCURSORINFO's Type parameter }
CU_CLIENT = $00000001;
CU_SERVER = $00000002;
CU_KEYSET = $00000004;
CU_MIXED = $00000008;
CU_DYNAMIC = $00000010;
CU_FORWARD = $00000020;
CU_INSENSITIVE = $00000040;
CU_READONLY = $00000080;
CU_LOCKCC = $00000100;
CU_OPTCC = $00000200;
CU_OPTCCVAL = $00000400;
{ Following are values used by DBCURSORINFO's Status parameter }
CU_FILLING = $00000001;
CU_FILLED = $00000002;
{ Following are values used by dbupdatetext's type parameter }
UT_TEXTPTR = $0001;
UT_TEXT = $0002;
UT_MORETEXT = $0004;
UT_DELETEONLY = $0008;
UT_LOG = $0010;
{ The following values are passed to dbserverenum for searching criteria. }
NET_SEARCH = $0001;
LOC_SEARCH = $0002;
{ These constants are the possible return values from dbserverenum. }
ENUM_SUCCESS = $0000;
MORE_DATA = $0001;
NET_NOT_AVAIL = $0002;
OUT_OF_MEMORY = $0004;
NOT_SUPPORTED = $0008;
ENUM_INVALID_PARAM = $0010;
{ Netlib Error problem codes. ConnectionError() should return one of }
{ these as the dblib-mapped problem code, so the corresponding string }
{ is sent to the dblib app's error handler as dberrstr. Return NE_E_NOMAP }
{ for a generic DB-Library error string (as in prior versions of dblib). }
NE_E_NOMAP = 0; { No string; uses dblib default. }
NE_E_NOMEMORY = 1; { Insufficient memory. }
NE_E_NOACCESS = 2; { Access denied. }
NE_E_CONNBUSY = 3; { Connection is busy. }
NE_E_CONNBROKEN = 4; { Connection broken. }
NE_E_TOOMANYCONN = 5; { Connection limit exceeded. }
NE_E_SERVERNOTFOUND = 6; { Specified SQL server not found. }
NE_E_NETNOTSTARTED = 7; { The network has not been started. }
NE_E_NORESOURCE = 8; { Insufficient network resources. }
NE_E_NETBUSY = 9; { Network is busy. }
NE_E_NONETACCESS = 10; { Network access denied. }
NE_E_GENERAL = 11; { General network error. Check your documentation. }
NE_E_CONNMODE = 12; { Incorrect connection mode. }
NE_E_NAMENOTFOUND = 13; { Name not found in directory service. }
NE_E_INVALIDCONN = 14; { Invalid connection. }
NE_E_NETDATAERR = 15; { Error reading or writing network data. }
NE_E_TOOMANYFILES = 16; { Too many open file handles. }
NE_E_CANTCONNECT = 17; { SQL Server does not exist or access denied. }
NE_MAX_NETERROR = 17;
const
MAXSERVERNAME = 30;
MAXNETLIBNAME = 255;
MAXNETLIBCONNSTR = 255;
const
INVALID_UROWNUM = Cardinal(-1);
{ common TDS protocol Data Type mapping of ntwdblib, dblib, freeTDS }
type
{ tabular data stream protocol types }
//Enum ordinal-value
TTDSType = (
tdsVoid = 31,
tdsImage = 34,
tdsText = 35,
tdsUnique = 36, //Unique identifier type
tdsVarBinary = 37,
tdsIntN = 38,
tdsVarchar = 39,
tdsMsDate = 40, // FreeTDS calls this SYBMSDATE, but it doesn't fit into the names nicely...
tdsMsTime = 41, // FreeTDS calls this SYBMSTIME, but it doesn't fit into the names nicely...
tdsMsDateTime2 = 42, // FreeTDS calls this SYBMSDATETIME", but it doesn't fit into the names nicely...
tdsMsDateTimeOffset = 43, // FreeTDS calls this SYBMSDATETIMEOFFSET, but it doesn't fit into the names nicely...
tdsBinary = 45,
tdsChar = 47,
tdsInt1 = 48,
tdsBit = 50,
tdsInt2 = 52,
tdsInt4 = 56,
tdsDateTime4 = 58,
tdsFlt4 = 59,
tdsMoney = 60,
tdsDateTime = 61,
tdsFlt8 = 62,
tdsVariant = 98, {from tds.h -> sybase only}
tdsNText = 99, {from tds.h -> sybase only}
tdsNVarChar = 103, {from tds.h -> sybase only}
tdsBitN = 104, {from tds.h -> sybase only}
tdsDecimal = 106,
tdsNumeric = 108,
tdsFltN = 109,
tdsMoneyN = 110,
tdsDateTimeN = 111,
tdsMoney4 = 122,
{from tds.h -> sade, sybase only}
tdsInt8 = 127,
tdsBigVarBinary = 165,
tdsBigVarChar = 167,
tdsBigBinary = 173,
tdsBigChar = 175,
tdsSybaseLongBinary = 225,
tdsBigNVarChar = 231,
tdsBigNChar = 239,
tdsUDT = 240,
tdsMSXML = 241
);
const
{ different type mappings / copied from tds.h -> sybase only!}
SYBAOPCNT = $4b;
SYBAOPCNTU = $4c;
SYBAOPSUM = $4d;
SYBAOPSUMU = $4e;
SYBAOPAVG = $4f;
SYBAOPAVGU = $50;
SYBAOPMIN = $51;
SYBAOPMAX = $52;
{ mssql2k compute operator }
SYBAOPCNT_BIG = $09;
SYBAOPSTDEV = $30;
SYBAOPSTDEVP = $31;
SYBAOPVAR = $32;
SYBAOPVARP = $33;
SYBAOPCHECKSUM_AGG = $72;
{****************** Plain API Types definition *****************}
type
{ DBPROCESS, LOGINREC and DBCURSOR }
PDBPROCESS = Pointer;
PLOGINREC = Pointer;
PDBCURSOR = Pointer;
PDBHANDLE = Pointer;
DBXLATE = Pointer;
DBSORTORDER = Pointer;
DBLOGINFO = Pointer;
DBVOIDPTR = PPointer;
type
{ DB-Library datatypes }
DBBOOL = Byte;
DBCHAR = AnsiChar;
DBBIT = Byte;
DBTINYINT = Byte;
DBSMALLINT = SmallInt; { int16_type }
DBINT = LongInt; { int32_type }
DBBIGINT = Int64; { int64_type }
DBBINARY = Byte;
DBFLT4 = Single; { real32_type }
DBFLT8 = Double; { real64_type }
DBSHORT = SmallInt;
DBUSMALLINT = Word;
DBMONEY4 = LongInt;
PDBMONEY4 = ^DBMONEY4;
RETCODE = Integer;
PRETCODE = ^RETCODE;
STATUS = Integer;
type
tdsVARYCHAR=packed record
len: DBINT;
str: array[0..DBMAXCHAR-1] of DBCHAR;
end;
dblibVARYCHAR=packed record
len: DBSMALLINT;
str: array[0..DBMAXCHAR-1] of DBCHAR;
end;
DBREAL = DBFLT4;
DBUBOOL = Cardinal;
DBDATETIM4 = packed record
numdays: Word; { No of days since Jan-1-1900 }
nummins: Word; { No. of minutes since midnight }
end;
PDBDATETIM4 = ^DBDATETIM4;
{$IFDEF FPC}
{$PACKRECORDS C}
{$ENDIF}
type
TDBNUMERIC = packed record
Precision: Byte;
Scale: Byte;
Sign: Byte; { 1 = Positive, 0 = Negative }
Val: array[0..MAXNUMERICLEN-1] of Byte;
end;
TDBDECIMAL = TDBNUMERIC;
PTDSDBNUMERIC = ^TTDSDBNUMERIC;
TTDSDBNUMERIC = packed record
Precision: Byte;
Scale: Byte;
Val: array[0..32] of Byte;
end;
TTDSDBDECIMAL = TTDSDBNUMERIC;
DBVARYCHAR = packed record
Len: DBSMALLINT;
Str: array[0..DBMAXCHAR-1] of DBCHAR;
end;
DBVARYBIN = packed record
Len: DBSMALLINT;
Bytes: array[0..DBMAXCHAR-1] of Byte;
end;
TDBMONEY = packed record
mnyhigh: DBINT;
mnylow: LongWord;
end;
PDBMONEY = ^TDBMONEY;
PDBDATETIME = ^TDBDATETIME;
TDBDATETIME = packed record
dtdays: DBINT; // Days since Jan 1, 1900
dttime: LongWord; // 300ths of a second since midnight, 25920000 unit is 1 day
end;
PTDSDBDATETIME = ^TTDSDBDATETIME;
TTDSDBDATETIME = packed record
dtdays: DBINT; // Days since Jan 1, 1900
dttime: DBINT; // 300ths of a second since midnight, 25920000 unit is 1 day
end;
TDBDATETIMEALL = packed record
time: UInt64;
date: DBINT;
offset: DBSMALLINT;
flags: Word;
end;
PDBDATETIMEALL = ^TDBDATETIMEALL;
const
DbDateTimeAllTimePrecMask = $0007;
DbDateTimeAllHasTimeMask = $2000;
DbDateTimeAllHasDateMask = $4000;
DbDatetimeAllHasOffsetMask = $8000;
(*
* Sybase & Microsoft use different names for the dbdaterec members.
* Keep these two structures physically identical in memory.
* dbdatecrack() casts one to the other for ease of implementation.
*
* Giving credit where credit is due, we can acknowledge that
* Microsoft chose the better names here, hands down. ("datedmonth"?!)
*)
type
{ FreeTDS sybdb.h }
PTDS_DBDATEREC = ^Ttds_dbdaterec;
Ttds_dbdaterec = packed record
{ fields } {microsoft} {sybase}
year: DBINT; { 1753 - 9999 } { 1900 and counting }
quarter: DBINT; { 1 - 4 } { 0 - 3 (Microsoft only) }
month: DBINT; { 1 - 12 } { 0 - 11 }
dayofmonth: DBINT; { 1 - 31 } { 1 - 31 }
dayofyear: DBINT; { 1 - 366 } { 1 - 366 (in Sybase.sybdb.h dayofyear and day are changed around!) }
week: DBINT; { 1 - 54 (for leap years) } { 1 - 54 (Microsoft only) }
weekday: DBINT; { 1 - 7 (Mon - Sun) } { 0 - 6 (Mon - Sun) }
hour: DBINT; { 0 - 23 } { 0 - 23 }
minute: DBINT; { 0 - 59 } { 0 - 59 }
second: DBINT; { 0 - 59 } { 0 - 59 }
millisecond: DBINT; { 0 - 999 } { 0 - 997 }
tzone: DBINT; { 0 - 127 (Sybase only!) } { 0 - 127 }
end;
{ DBDATEREC structure used by dbdatecrack }
DBDATEREC = packed record
year: DBINT; { 1753 - 9999 }
quarter: DBINT; { 1 - 4 }
month: DBINT; { 1 - 12 }
dayofyear: DBINT; { 1 - 366 }
day: DBINT; { 1 - 31 }
week: DBINT; { 1 - 54 (for leap years) }
weekday: DBINT; { 1 - 7 (Mon - Sun) }
hour: DBINT; { 0 - 23 }
minute: DBINT; { 0 - 59 }
second: DBINT; { 0 - 59 }
millisecond: DBINT; { 0 - 999 }
end;
PDBDATEREC = ^DBDATEREC;
type
//EH: We need a size of 122 Bytes!
{$IFDEF FPC}
{$PACKRECORDS 1}
{$ELSE}
{$A1} //JBau: Does this really make sense? I didn't find documentation for anything besides $A+ and $A- about this.
{$ENDIF}
PZDBCOL = ^ZDBCOL;
ZDBCOL = packed record
Typ: DBSHORT;
UserType: DBINT;
MaxLength: DBINT;
Precision: BYTE;
Scale: BYTE;
PAD1: BYTE; // JBau: These pads are necessary because otherwise we cannot get the sams memory layout as C uses :o(
PAD2: BYTE; // JBau: These pads are necessary because otherwise we cannot get the sams memory layout as C uses :o(
VarLength: LongBool; { TRUE, FALSE }
Null: BYTE; { TRUE, FALSE or DBUNKNOWN }
CaseSensitive: BYTE; { TRUE, FALSE or DBUNKNOWN }
Updatable: BYTE; { TRUE, FALSE or DBUNKNOWN }
PAD3: BYTE; // JBau: These pads are necessary because otherwise we cannot get the sams memory layout as C uses :o(
Identity: LongBool; { TRUE, FALSE or DBUNKNOWN }
end;
PDBCOL = ^DBCOL;
DBCOL = packed record
SizeOfStruct: DBINT;
Name: array[0..MAXCOLNAMELEN] of DBCHAR;
ActualName: array[0..MAXCOLNAMELEN] of DBCHAR;
TableName: array[0..MAXTABLENAME] of DBCHAR;
ColInfo: ZDBCOL;
(*Typ: DBSHORT;
UserType: DBINT;
MaxLength: DBINT;
Precision: BYTE;
Scale: BYTE;
VarLength: LongBool; { TRUE, FALSE }
Null: BYTE; { TRUE, FALSE or DBUNKNOWN }
CaseSensitive: BYTE; { TRUE, FALSE or DBUNKNOWN }
Updatable: BYTE; { TRUE, FALSE or DBUNKNOWN }
Identity: LongBool; { TRUE, FALSE or DBUNKNOWN }*)
end;
PTDSDBCOL = ^TTDSDBCOL;
TTDSDBCOL = packed record
SizeOfStruct: DBINT;
Name: array[0..TDSMAXCOLNAMELEN+1] of DBCHAR;
ActualName: array[0..TDSMAXCOLNAMELEN+1] of DBCHAR;
TableName: array[0..TDSMAXCOLNAMELEN+1] of DBCHAR;
ColInfo: ZDBCOL;
(*Typ: SmallInt;
UserType: DBINT;
MaxLength: DBINT;
Precision: Byte;
Scale: Byte;
VarLength: LongBool;{ TRUE, FALSE }
Null: Byte; { TRUE, FALSE or DBUNKNOWN }
CaseSensitive: Byte; { TRUE, FALSE or DBUNKNOWN }
Updatable: Byte; { TRUE, FALSE or DBUNKNOWN }
Identity: LongBool;{ TRUE, FALSE }*)
end;
PTDSDBCOL2 = ^TTDSDBCOL;
TTDSDBCOL2 = packed record
SizeOfStruct: DBINT;
Name: array[0..TDSMAXCOLNAMELEN+1] of DBCHAR;
ActualName: array[0..TDSMAXCOLNAMELEN+1] of DBCHAR;
TableName: array[0..TDSMAXCOLNAMELEN+1] of DBCHAR;
Typ: SmallInt;
UserType: DBINT;
MaxLength: DBINT;
Precision: Byte;
Scale: Byte;
VarLength: LongBool;{ TRUE, FALSE }
Null: Byte; { TRUE, FALSE or DBUNKNOWN }
CaseSensitive: Byte; { TRUE, FALSE or DBUNKNOWN }
Updatable: Byte; { TRUE, FALSE or DBUNKNOWN }
Identity: LongBool;{ TRUE, FALSE }
ServerType: DBSHORT;
ServerMaxLength:DBINT;
ServerTypeDeclaration:array[Byte] of AnsiChar;
end;
{$IFDEF FPC}
{$PACKRECORDS DEFAULT}
{$ELSE}
{$A+}
{$ENDIF}
type
PDBTYPEINFO = ^TDBTYPEINFO;
TDBTYPEINFO = packed record
Precision: DBINT;
Scale: DBINT;
end;
DBPROC_INFO = packed record
SizeOfStruct: DBINT;
ServerType: Byte;
ServerMajor: Word;
ServerMinor: Word;
ServerRevision: Word;
ServerName: array[0..MAXSERVERNAME] of AnsiChar;
NetLibName: array[0..MAXNETLIBNAME] of AnsiChar;
NetLibConnStr: array[0..MAXNETLIBCONNSTR] of AnsiChar;
end;
PDBPROCINFO = ^DBPROC_INFO;
DBCURSOR_INFO = packed record
SizeOfStruct: DBINT; { Use sizeof(DBCURSORINFO) }
TotCols: Cardinal; { Total Columns in cursor }
TotRows: Cardinal; { Total Rows in cursor }
CurRow: Cardinal; { Current actual row in server }
TotRowsFetched: Cardinal; { Total rows actually fetched }
CurType: Cardinal; { See CU_... }
Status: Cardinal; { See CU_... }
end;
PDBCURSORINFO = ^DBCURSOR_INFO;
type
{ Pointer Datatypes }
PDBINT = ^DBINT;
PDBBINARY = ^DBBINARY;
type
PDBLibError = ^TDBLibError;
TDBLibError = record
dbProc: PDBPROCESS;
Severity: DBINT;
DbErr: DBINT;
OsErr: DBINT;
DbErrStr: RawByteString;
OsErrStr: RawByteString;
end;
PDBLibMessage = ^TDBLibMessage;
TDBLibMessage = record
dbProc: PDBPROCESS;
MsgNo: DBINT;
MsgState: DBINT;
Severity: DBINT;
MsgText: RawByteString;
SrvName: RawByteString;
ProcName: RawByteString;
Line: DBUSMALLINT;
end;
{** Represents a generic interface to DBLIB native API. }
IZDBLibPlainDriver = interface (IZPlainDriver)
['{7731C3B4-0608-4B6B-B089-240AC43A3463}']
end;
TDBERRHANDLE_PROC_cdecl = function(Proc: PDBPROCESS; Severity, DbErr, OsErr: Integer;
DbErrStr, OsErrStr: PAnsiChar): Integer; cdecl;
TDBMSGHANDLE_PROC_cdecl = function(Proc: PDBPROCESS; MsgNo: DBINT; MsgState,
Severity: Integer; MsgText, SrvName, ProcName: PAnsiChar; Line: DBUSMALLINT):
Integer; cdecl;
{$IFDEF MSWINDOWS}
TDBERRHANDLE_PROC_stdcall = function(Proc: PDBPROCESS; Severity, DbErr, OsErr: Integer;
DbErrStr, OsErrStr: PAnsiChar): Integer; stdcall;
TDBMSGHANDLE_PROC_stdcall = function(Proc: PDBPROCESS; MsgNo: DBINT; MsgState,
Severity: Integer; MsgText, SrvName, ProcName: PAnsiChar; Line: DBUSMALLINT):
Integer; stdcall;
{$ENDIF}
TZDBLibErrorList = Class(TZCustomElementList)
protected
/// <summary>Notify about an action which will or was performed.
/// if ElementNeedsFinalize is False the method will never be called.
/// Otherwise you may finalize managed types beeing part of each element,
/// such as Strings, Objects etc.</summary>
/// <param>"Ptr" the address of the element an action happens for.</param>
/// <param>"Index" the index of the element.</param>
/// <returns>The address or raises an EListError if the Index is invalid.</returns>
procedure Notify(Ptr: Pointer; Action: TListNotification); override;
public
constructor Create;
End;
TZDBLibMessageList = Class(TZCustomElementList)
protected
/// <summary>Notify about an action which will or was performed.
/// if ElementNeedsFinalize is False the method will never be called.
/// Otherwise you may finalize managed types beeing part of each element,
/// such as Strings, Objects etc.</summary>
/// <param>"Ptr" the address of the element an action happens for.</param>
/// <param>"Index" the index of the element.</param>
/// <returns>The address or raises an EListError if the Index is invalid.</returns>
procedure Notify(Ptr: Pointer; Action: TListNotification); override;
public
constructor Create;
End;
{$IFDEF TEST_CALLBACK}
TDBERRHANDLE_PROC = function(Proc: PDBPROCESS; Severity, DbErr, OsErr: Integer;
DbErrStr, OsErrStr: PAnsiChar): Integer of Object;
TDBMSGHANDLE_PROC = function(Proc: PDBPROCESS; MsgNo: DBINT; MsgState,
Severity: Integer; MsgText, SrvName, ProcName: PAnsiChar; Line: DBUSMALLINT): Integer of Object;
IZDBLibErrorHandler = interface(IZInterface)
['{E853EAE4-3E13-45FD-9483-726D25A7930E}']
end;
IZDBLibMessageHandler = interface(IZInterface)
['{2B0CB89E-7C17-4C38-B5C4-677C483672AF}']
end;
TDbLibErrorHandler = class; //forward
TDbLibMessageHandler = class; //forward
{$ENDIF TEST_CALLBACK}
TDBLibraryVendorType = (lvtFreeTDS, lvtMS, lvtSybase);
TZDBLIBPLainDriver = class(TZAbstractPlainDriver, IZPlainDriver)
private
{$IFDEF TEST_CALLBACK}
FSQLErrorHandlerList: TZDBLibErrorList;
FSQLMessageHandlerList: TZDBLibMessageList;
FCS: TCriticalSection;
{$ENDIF TEST_CALLBACK}
{$IFDEF MSWINDOWS}FClientVersion: String;{$ENDIF}
private
{ core }
{$IFDEF MSWINDOWS}
Fdbadata: function(dbproc: PDBPROCESS; ComputeId, Column: Integer): PByte; cdecl;
Fdbadata_stdcall: function(dbproc: PDBPROCESS; ComputeId, Column: Integer): PByte; stdcall;
Fdbadlen: function(dbproc: PDBPROCESS; ComputeId, Column: Integer): DBINT; cdecl;
Fdbadlen_stdcall: function(dbproc: PDBPROCESS; ComputeId, Column: Integer): DBINT; stdcall;
Fdbaltbind: function(dbproc: PDBPROCESS; ComputeId, Column, VarType: Integer; VarLen: DBINT; VarAddr: PByte): RETCODE; cdecl;
Fdbaltbind_stdcall: function(dbproc: PDBPROCESS; ComputeId, Column, VarType: Integer; VarLen: DBINT; VarAddr: PByte): RETCODE; stdcall;
Fdbaltbind_ps: function(dbproc: PDBPROCESS; ComputeId, Column: Integer; VarType: Integer; VarLen: DBINT; VarAddr: PByte; typinfo: PDBTYPEINFO): RETCODE; cdecl;
Fdbaltbind_ps_stdcall: function(dbproc: PDBPROCESS; ComputeId, Column: Integer; VarType: Integer; VarLen: DBINT; VarAddr: PByte; typinfo: PDBTYPEINFO): RETCODE; stdcall;
Fdbaltcolid: function(dbproc: PDBPROCESS; ComputeId, Column: Integer): Integer; cdecl;
Fdbaltcolid_stdcall: function(dbproc: PDBPROCESS; ComputeId, Column: Integer): Integer; stdcall;
Fdbaltlen: function(dbproc: PDBPROCESS; ComputeId, Column: Integer): DBINT; cdecl;
Fdbaltlen_stdcall: function(dbproc: PDBPROCESS; ComputeId, Column: Integer): DBINT; stdcall;
Fdbaltop: function(dbproc: PDBPROCESS; ComputeId, Column: Integer): Integer; cdecl;
Fdbaltop_stdcall: function(dbproc: PDBPROCESS; ComputeId, Column: Integer): Integer; stdcall;
Fdbalttype: function(dbproc: PDBPROCESS; ComputeId, Column: Integer): Integer; cdecl;
Fdbalttype_stdcall: function(dbproc: PDBPROCESS; ComputeId, Column: Integer): Integer; stdcall;
Fdbaltutype: function(dbproc: PDBPROCESS; ComputeId, Column: Integer): DBINT; cdecl;
Fdbaltutype_stdcall: function(dbproc: PDBPROCESS; ComputeId, Column: Integer): DBINT; stdcall;
Fdbanullbind: function(dbproc: PDBPROCESS; ComputeId, Column: Integer; Indicator: PDBINT): RETCODE; cdecl;
Fdbanullbind_stdcall: function(dbproc: PDBPROCESS; ComputeId, Column: Integer; Indicator: PDBINT): RETCODE; stdcall;
Fdbbind: function(dbproc: PDBPROCESS; Column, VarType, VarLen: Integer; VarAddr: PByte): RETCODE; cdecl;
Fdbbind_stdcall: function(dbproc: PDBPROCESS; Column, VarType, VarLen: Integer; VarAddr: PByte): RETCODE; stdcall;
Fdbbind_ps: function (dbproc: PDBPROCESS; Column, VarType, VarLen: Integer; VarAddr: PByte; typinfo: PDBTYPEINFO): RETCODE; cdecl;
Fdbbind_ps_stdcall: function (dbproc: PDBPROCESS; Column, VarType, VarLen: Integer; VarAddr: PByte; typinfo: PDBTYPEINFO): RETCODE; stdcall;
Fdbbufsize: function(dbproc: PDBPROCESS): Integer; cdecl;
Fdbbufsize_stdcall: function(dbproc: PDBPROCESS): Integer; stdcall;
Fdbbylist: function(dbproc: PDBPROCESS; ComputeId: Integer; Size: PInteger): PByte; cdecl;
Fdbbylist_stdcall: function(dbproc: PDBPROCESS; ComputeId: Integer; Size: PInteger): PByte; stdcall;
Fdbcancel: function(dbproc: PDBPROCESS): RETCODE; cdecl;
Fdbcancel_stdcall: function(dbproc: PDBPROCESS): RETCODE; stdcall;
Fdbcanquery: function(dbproc: PDBPROCESS): RETCODE; cdecl;
Fdbcanquery_stdcall: function(dbproc: PDBPROCESS): RETCODE; stdcall;
Fdbchange: function(dbproc: PDBPROCESS): PAnsiChar; cdecl;
Fdbchange_stdcall: function(dbroc: PDBPROCESS): PAnsiChar; stdcall;
//dbcharsetconv
{EH: Attention -> call convention and ms version returns a RETCODE}
Fdbclose_SYB: procedure(dbproc: PDBPROCESS); cdecl;
Fdbclose_MS: function(dbproc: PDBPROCESS): RETCODE; cdecl;
Fdbclose_stdcall: procedure(dbproc: PDBPROCESS); stdcall;
Fdbclrbuf: procedure(dbproc: PDBPROCESS; N: DBINT); cdecl;
Fdbclrbuf_stdcall: procedure(dbproc: PDBPROCESS; N: DBINT); stdcall;
Fdbclropt: function(dbproc: PDBPROCESS; Option: Integer; Param: PAnsiChar): RETCODE; cdecl;
Fdbclropt_stdcall: function(dbproc: PDBPROCESS; Option: Integer; Param: PAnsiChar): RETCODE; stdcall;
Fdbcmd: function(dbproc: PDBPROCESS; Cmd: PAnsiChar): RETCODE; cdecl;
Fdbcmd_stdcall: function(dbproc: PDBPROCESS; Cmd: PAnsiChar): RETCODE; stdcall;
Fdbcmdrow: function(dbproc: PDBPROCESS): RETCODE; cdecl;
Fdbcmdrow_stdcall: function(dbproc: PDBPROCESS): RETCODE; stdcall;
//result type(MS vs Syb) size is different
Fdbcolbrowse_MS: function(dbproc: PDBPROCESS; Column: Integer): LongBool; cdecl;
Fdbcolbrowse_SYB: function(dbproc: PDBPROCESS; Column: Integer): DBBOOL; cdecl; //no FreeTDS?
Fdbcolbrowse_stdcall: function(dbproc: PDBPROCESS; Column: Integer): DBBOOL; stdcall;
Fdbcollen: function(dbproc: PDBPROCESS; Column: Integer): DBINT; cdecl;
Fdbcollen_stdcall: function(dbproc: PDBPROCESS; Column: Integer): DBINT; stdcall;
Fdbcolname: function(dbproc: PDBPROCESS; Column: Integer): PAnsiChar; cdecl;
Fdbcolname_stdcall: function(dbproc: PDBPROCESS; Column: Integer): PAnsiChar; stdcall;
Fdbcolsource: function(dbproc: PDBPROCESS; Column: Integer): PAnsiChar; cdecl; //no FreeTDS?
Fdbcolsource_stdcall: function(dbproc: PDBPROCESS; Column: Integer): PAnsiChar; stdcall;
Fdbcoltype: function(dbproc: PDBPROCESS; Column: Integer): Integer; cdecl;
Fdbcoltype_stdcall: function(dbproc: PDBPROCESS; Column: Integer): Integer; stdcall;
Fdbcoltypeinfo: function(dbproc: PDBPROCESS; Column: Integer): PDBTYPEINFO; cdecl; //no MS
Fdbcoltypeinfo_stdcall: function(dbproc: PDBPROCESS; Column: Integer): PDBTYPEINFO; stdcall;
Fdbcolutype: function(dbproc: PDBPROCESS; Column: Integer): DBINT; cdecl;
Fdbcolutype_stdcall: function(dbproc: PDBPROCESS; Column: Integer): DBINT; stdcall;
Fdbconvert: function(dbproc: PDBPROCESS; SrcType: Integer; Src: PByte;
SrcLen: DBINT; DestType: Integer; Dest: PByte; DestLen: DBINT): Integer; cdecl;
Fdbconvert_stdcall: function(dbproc: PDBPROCESS; SrcType: Integer; Src: PByte;
SrcLen: DBINT; DestType: Integer; Dest: PByte; DestLen: DBINT): Integer; stdcall;
Fdbconvert_ps: function(dbproc: PDBPROCESS; SrcType: Integer; Src: PByte;
SrcLen: DBINT; DestType: Integer; Dest: PByte; DestLen: DBINT; typinfo: PDBTYPEINFO): Integer; cdecl; //NO MS
Fdbconvert_ps_stdcall: function(dbproc: PDBPROCESS; SrcType: Integer; Src: PByte;
SrcLen: DBINT; DestType: Integer; Dest: PByte; DestLen: DBINT; typinfo: PDBTYPEINFO): Integer; stdcall;
Fdbcount: function(dbproc: PDBPROCESS): DBINT; cdecl;
Fdbcount_stdcall: function(dbproc: PDBPROCESS): DBINT; stdcall;
Fdbcurcmd_MS: function(dbproc: PDBPROCESS): Integer; cdecl;
Fdbcurcmd_SYB: function(dbproc: PDBPROCESS): DBINT; cdecl;
Fdbcurcmd_stdcall: function(dbproc: PDBPROCESS): DBINT; stdcall;
Fdbcurrow: function(dbproc: PDBPROCESS): DBINT; cdecl;
Fdbcurrow_stdcall: function(dbproc: PDBPROCESS): DBINT; stdcall;
Fdbdata: function(dbproc: PDBPROCESS; Column: Integer): PByte; cdecl;
Fdbdata_stdcall: function(dbproc: PDBPROCESS; Column: Integer): PByte; stdcall;
//Fdbdatecrack: function(Proc: PDBPROCESS; DateInfo: PDBDATEREC; DateType: PDBDATETIME): RETCODE; cdecl;
//Fdbdatecrack_stdcall: function(Proc: PDBPROCESS; DateInfo: PDBDATEREC; DateType: PDBDATETIME): RETCODE; cdecl;
//Fdbdatecrack_TDS: function(dbproc: PDBPROCESS; DateInfo: PTDS_DBDATEREC; DateType: PTDSDBDATETIME): RETCODE; cdecl;
Fdbdatlen: function(dbproc: PDBPROCESS; Column: Integer): DBINT; cdecl;
Fdbdatlen_stdcall: function(dbproc: PDBPROCESS; Column: Integer): DBINT; stdcall;
Fdbdead_MS: function(dbroc: PDBPROCESS): LongBool; cdecl;
Fdbdead: function(dbroc: PDBPROCESS): DBBOOL; cdecl;
Fdbdead_stdcall: function(dbproc: PDBPROCESS): DBBOOL; stdcall;
Fdbexit: procedure; cdecl;
Fdbexit_stdcall: procedure; stdcall;
FdbHasRetStat_MS: function(dbProc: PDBPROCESS): LongBool; cdecl;
FdbHasRetStat_SYB: function(dbProc: PDBPROCESS): DBBOOL; cdecl;
FdbHasRetStat_stdcall: function(dbProc: PDBPROCESS): DBBOOL; stdcall;
{Fdbfcmd: function(Proc: PDBPROCESS; CmdString: PAnsiChar; var Params): RETCODE; cdecl;
Fdbfcmd_stdcall: function(Proc: PDBPROCESS; CmdString: PAnsiChar; var Params): RETCODE; stdcall;}
Fdbfirstrow: function(Proc: PDBPROCESS): DBINT; cdecl;
Fdbfirstrow_stdcall: function(Proc: PDBPROCESS): DBINT; stdcall;
Fdbfreebuf: procedure(Proc: PDBPROCESS); cdecl;
Fdbfreebuf_stdcall: procedure(Proc: PDBPROCESS); stdcall;
Fdbfreequal: procedure(Ptr: PAnsiChar); cdecl;
Fdbfreequal_stdcall: procedure(Ptr: PAnsiChar); stdcall;
Fdbgetchar: function(Proc: PDBPROCESS; N: Integer): PAnsiChar; cdecl;
Fdbgetchar_stdcall: function(Proc: PDBPROCESS; N: Integer): PAnsiChar; stdcall;
Fdbgetcharset: function(dbproc: PDBPROCESS): PAnsiChar; cdecl; //NO MS
Fdbgetcharset_stdcall: function(dbproc: PDBPROCESS): PAnsiChar; stdcall;
FdbGetRow: function(dbProc: PDBPROCESS; Row: DBINT): STATUS; cdecl;
FdbGetRow_stdcall: function(dbProc: PDBPROCESS; Row: DBINT): STATUS; stdcall;
FdbInit_MS: function: PAnsiChar; cdecl; //returns the librayversion
FdbInit: function: RETCODE; cdecl;
FdbInit_stdcall: function: RETCODE; stdcall; //SYBASE returns SUCCEED or FAIL
FdbLogin_stdcall: function: PLOGINREC; stdcall;
Fdbloginfree: procedure(loginptr: PLOGINREC); cdecl;
Fdbloginfree_stdcall: procedure(loginptr: PLOGINREC); stdcall;
FdbMoreCmds: function(dbProc: PDBPROCESS): RETCODE; cdecl;
FdbMoreCmds_stdcall: function(dbProc: PDBPROCESS): RETCODE; stdcall;
FdbName: function(dbProc: PDBPROCESS): PAnsiChar; cdecl;
FdbName_stdcall: function(dbProc: PDBPROCESS): PAnsiChar; stdcall;
FdbNextRow: function(dbProc: PDBPROCESS): STATUS; cdecl;
FdbNextRow_stdcall: function(dbProc: PDBPROCESS): STATUS; stdcall;
FdbNumCols: function(dbProc: PDBPROCESS): DBINT; cdecl;
FdbNumCols_stdcall: function(dbProc: PDBPROCESS): DBINT; stdcall;
FdbOpen: function(Login: PLOGINREC; server: PAnsiChar): PDBPROCESS; cdecl;
FdbOpen_stdcall: function(Login: PLOGINREC; server: PAnsiChar): PDBPROCESS; stdcall;
FtdsDbOpen: function(Login: PLOGINREC; server: PAnsiChar; msdblib: Integer): PDBPROCESS; cdecl;
FdbResults: function(dbProc: PDBPROCESS): RETCODE; cdecl;
FdbResults_stdcall: function(dbProc: PDBPROCESS): RETCODE; stdcall;
FdbRetData: function(dbProc: PDBPROCESS; RetNum: Integer): Pointer; cdecl;
FdbRetData_stdcall: function(dbProc: PDBPROCESS; RetNum: Integer): Pointer; stdcall;
FdbRetStatus: function(dbProc: PDBPROCESS): DBINT; cdecl;
FdbRetStatus_stdcall: function(dbProc: PDBPROCESS): DBINT; stdcall;
FdbRetType: function(dbProc: PDBPROCESS; RetNum: DBINT): DBINT; cdecl;
FdbRetType_stdcall: function(dbProc: PDBPROCESS; RetNum: DBINT): DBINT; stdcall;
{rpc i.e remote procedure calls }
FdbRpcInit: function(dbProc: PDBPROCESS; RpcName: PAnsiChar; Options: DBSMALLINT): RETCODE; cdecl;
FdbRpcInit_stdcall: function(dbProc: PDBPROCESS; RpcName: PAnsiChar; Options: DBSMALLINT): RETCODE; stdcall;
FdbRpcParam: function(dbProc: PDBPROCESS; ParamName: PAnsiChar; Status: Byte;
Type_: DBINT; MaxLen: DBINT; DataLen: DBINT; Value: Pointer): RETCODE; cdecl;
FdbRpcParam_stdcall: function(dbProc: PDBPROCESS; ParamName: PAnsiChar; Status: Byte;
Type_: DBINT; MaxLen: DBINT; DataLen: DBINT; Value: Pointer): RETCODE; stdcall;
FdbRpcSend: function(dbProc: PDBPROCESS): RETCODE; cdecl;
FdbRpcSend_stdcall: function(dbProc: PDBPROCESS): RETCODE; cdecl;
FdbRpcExec: function(dbProc: PDBPROCESS): RETCODE; cdecl; //MS only
FdbRetLen: function(dbProc: PDBPROCESS; RetNum: Integer): DBINT; cdecl;
FdbRetLen_stdcall: function(dbProc: PDBPROCESS; RetNum: Integer): DBINT; stdcall;
FdbRetName: function(dbProc: PDBPROCESS; RetNum: Integer): PAnsiChar; cdecl;
FdbRetName_stdcall: function(dbProc: PDBPROCESS; RetNum: Integer): PAnsiChar; stdcall;
FdbSqlExec: function(dbProc: PDBPROCESS): RETCODE; cdecl;
FdbSqlExec_stdcall: function(dbProc: PDBPROCESS): RETCODE; stdcall;
FdbSqlOk: function(dbProc: PDBPROCESS): RETCODE; cdecl;
FdbSqlOk_stdcall: function(dbProc: PDBPROCESS): RETCODE; stdcall;
Fdbsqlsend: function(dbProc: PDBPROCESS): RETCODE; cdecl;
Fdbsqlsend_stdcall: function(dbProc: PDBPROCESS): RETCODE; stdcall;
FdbSetLName: function(Login: PLOGINREC; Value: PAnsiChar; Item: Integer): RETCODE; cdecl;
FdbSetLName_stdcall: function(Login: PLOGINREC; Value: PAnsiChar; Item: Integer): RETCODE; stdcall;
FdbSetLoginTime: function(Seconds: Integer): RETCODE; cdecl;
FdbSetLoginTime_stdcall: function(Seconds: Integer): RETCODE; stdcall;
FdbSetOpt_MS: function(dbProc: PDBPROCESS; Option: Integer; Char_Param: PAnsiChar): RETCODE; cdecl;
FdbSetOpt_SYB: function(dbProc: PDBPROCESS; Option: Integer; Char_Param: PAnsiChar; Int_Param: Integer): RETCODE; cdecl;
FdbSetOpt_stdcall: function(dbProc: PDBPROCESS; Option: Integer; Char_Param: PAnsiChar; Int_Param: Integer): RETCODE; stdcall;
Fdbsetlpacket: function(Login: PLOGINREC; PacketSize: Word): RETCODE; cdecl; //MS only others use dbsetlname
FdbSetMaxprocs_S: function(MaxProcs: SmallInt): RETCODE; cdecl;
FdbSetMaxprocs_I: function(MaxProcs: DBINT): RETCODE; cdecl;
FdbSetMaxprocs_stdcall: function(MaxProcs: DBINT): RETCODE; stdcall; //sybase has widened the type!
FdbSetTime: function(Seconds: Integer): RETCODE; cdecl;
FdbSetTime_stdcall: function(Seconds: Integer): RETCODE; stdcall;
FdbUse: function(dbProc: PDBPROCESS; dbName: PAnsiChar): RETCODE; cdecl;
FdbUse_stdcall: function(dbProc: PDBPROCESS; dbName: PAnsiChar): RETCODE; stdcall;
Fdbvarylen_MS: function(Proc: PDBPROCESS; Column: Integer): LongBool; cdecl;
Fdbvarylen_SYB: function(Proc: PDBPROCESS; Column: Integer): DBBOOL; cdecl;
Fdbvarylen_stdcall: function(Proc: PDBPROCESS; Column: Integer): DBBOOL; stdcall;
Fdbversion: function(): PAnsiChar; cdecl;
Fdbversion_stdcall: function(): PAnsiChar; stdcall;
//Fdb12hour: function(dbproc: PDBPROCESS; Language: PAnsiChar): DBBOOL; cdecl; //no MS
//Fdb12hour_stdcall: function(dbproc: PDBPROCESS; Language: PAnsiChar): DBBOOL; stdcall; //no MS
dberrhandle_stdcall: function(Handler: TDBERRHANDLE_PROC_stdcall): TDBERRHANDLE_PROC_stdcall; stdcall;
dbmsghandle_stdcall: function(Handler: TDBMSGHANDLE_PROC_stdcall): TDBMSGHANDLE_PROC_stdcall; stdcall;
FdbSetVersion_stdcall: function(Version: DBINT): RETCODE; stdcall;
fdbWinexit: procedure; cdecl; // MS only
{$ENDIF}
//Fdbtds: function(dbproc: PDBPROCESS): DBINT; cdecl;
FdbLogin: function: PLOGINREC; cdecl;
private
FDBLibraryVendorType: TDBLibraryVendorType;
FdbSetVersion: function(Version: DBINT): RETCODE; cdecl;
protected
procedure LoadApi; override;
procedure LoadCodePages; override;
public
procedure AfterConstruction; override;
{$IFDEF TEST_CALLBACK}
procedure BeforeDestruction; override;
{$ENDIF TEST_CALLBACK}
destructor Destroy; override;
public //core
dberrhandle: function(Handler: TDBERRHANDLE_PROC_cdecl): TDBERRHANDLE_PROC_cdecl; cdecl;
dbmsghandle: function(Handler: TDBMSGHANDLE_PROC_cdecl): TDBMSGHANDLE_PROC_cdecl; cdecl;
dbsetlversion: function(Login: PLOGINREC; Version: Byte): RETCODE; cdecl; //just FreeTDS
tdsdump_on: procedure; cdecl;
tdsdump_off: procedure; cdecl;
tdsdump_open: function (FileName : PAnsiChar): Integer; cdecl;
tdsdump_close: procedure; cdecl;
//_tds_socket_init: procedure ; cdecl;
//_tds_socket_done: procedure ; cdecl;
{$IFDEF MSWINDOWS}
function dbadata(dbproc: PDBPROCESS; ComputeId, Column: Integer): PByte; {$IFDEF WITH_INLINE}inline;{$ENDIF}
function dbadlen(dbproc: PDBPROCESS; ComputeId, Column: Integer): DBINT; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbaltbind(dbproc: PDBPROCESS; ComputeId, Column, VarType: Integer;
VarLen: DBINT; VarAddr: PByte): RETCODE; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbaltbind_ps(dbproc: PDBPROCESS; ComputeId, Column: Integer; VarType: Integer;
VarLen: DBINT; VarAddr: PByte; typinfo: PDBTYPEINFO): RETCODE; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbaltcolid(dbproc: PDBPROCESS; ComputeId, Column: Integer): Integer; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbaltlen(dbproc: PDBPROCESS; ComputeId, Column: Integer): DBINT; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbaltop(dbproc: PDBPROCESS; ComputeId, Column: Integer): Integer; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbalttype(dbproc: PDBPROCESS; ComputeId, Column: Integer): Integer; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbaltutype(dbproc: PDBPROCESS; ComputeId, Column: Integer): DBINT; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbanullbind(dbproc: PDBPROCESS; ComputeId, Column: Integer; Indicator: PDBINT): RETCODE; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbbind(dbproc: PDBPROCESS; Column, VarType, VarLen: Integer; VarAddr: PByte): RETCODE; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbbind_ps(dbproc: PDBPROCESS; Column, VarType, VarLen: Integer; VarAddr: PByte; typinfo: PDBTYPEINFO): RETCODE; {$IFDEF WITH_INLINE}inline; {$ENDIF}//no MS
function dbbufsize(dbproc: PDBPROCESS): Integer; {$IFDEF WITH_INLINE}inline; {$ENDIF}//no MS
function dbbylist(dbproc: PDBPROCESS; ComputeId: Integer; Size: PInteger): PByte; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbcancel(dbproc: PDBPROCESS): RETCODE; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbcanquery(dbproc: PDBPROCESS): RETCODE; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbchange(dbproc: PDBPROCESS): PAnsiChar; {$IFDEF WITH_INLINE}inline; {$ENDIF}
procedure dbclose(dbproc: PDBPROCESS); {$IFDEF WITH_INLINE}inline; {$ENDIF}
procedure dbclrbuf(dbproc: PDBPROCESS; N: DBINT); {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbclropt(dbproc: PDBPROCESS; Option: Integer; Param: PAnsiChar): RETCODE; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbcmd(dbproc: PDBPROCESS; Cmd: PAnsiChar): RETCODE; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbcmdrow(dbproc: PDBPROCESS): RETCODE;{$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbcolbrowse(dbproc: PDBPROCESS; Column: Integer): DBBOOL; {$IFDEF WITH_INLINE}inline; {$ENDIF}
public dbcolinfo: function(pdbhandle: PDBHANDLE; _Type: Integer; Column: DBINT; ComputeId: DBINT; lpdbcol: PDBCOL): RETCODE; cdecl;//no SYB but FreeTDS
public dbtablecolinfo: function(pdbhandle: PDBHANDLE; Column: DBINT; lpdbcol: PDBCOL): RETCODE; cdecl;//FreeTDS only!
function dbcollen(dbproc: PDBPROCESS; Column: Integer): DBINT; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbcolname(dbproc: PDBPROCESS; Column: Integer): PAnsiChar; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbcolsource(dbproc: PDBPROCESS; Column: Integer): PAnsiChar; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbcoltype(dbproc: PDBPROCESS; Column: Integer): Integer; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbcolutype(dbproc: PDBPROCESS; Column: Integer): DBINT; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbcoltypeinfo(dbproc: PDBPROCESS; Column: Integer): PDBTYPEINFO; {$IFDEF WITH_INLINE}inline; {$ENDIF}//no MS
function dbconvert(dbproc: PDBPROCESS; SrcType: Integer; Src: PByte;
SrcLen: DBINT; DestType: Integer; Dest: PByte; DestLen: DBINT): Integer; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbconvert_ps(dbproc: PDBPROCESS; SrcType: Integer; Src: PByte;
SrcLen: DBINT; DestType: Integer; Dest: PByte; DestLen: DBINT; typinfo: PDBTYPEINFO): Integer; {$IFDEF WITH_INLINE}inline; {$ENDIF}//no MS
function dbcount(dbproc: PDBPROCESS): DBINT; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbcurcmd(dbproc: PDBPROCESS): DBINT; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbcurrow(dbproc: PDBPROCESS): DBINT; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbdata(dbproc: PDBPROCESS; Column: Integer): PByte; {$IFDEF WITH_INLINE}inline; {$ENDIF}
public dbdataready: function(Proc: PDBPROCESS): LongBool; cdecl; //MS only
function dbdatlen(dbproc: PDBPROCESS; Column: Integer): DBINT; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbdead(dbproc: PDBPROCESS): DBBOOL; {$IFDEF WITH_INLINE}inline; {$ENDIF}
//public dbenlisttrans: function(Proc: PDBPROCESS; PurposeUnkonwn: Longbool): RETCODE; cdecl; //MS only purpose is unknown
procedure dbexit; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbSqlExec(dbProc: PDBPROCESS): RETCODE; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbSqlOk(dbProc: PDBPROCESS): RETCODE; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbsqlsend(dbProc: PDBPROCESS): RETCODE; {$IFDEF WITH_INLINE}inline; {$ENDIF}
//function dbfcmd(Proc: PDBPROCESS; CmdString: PAnsiChar; var Params): RETCODE;
function dbfirstrow(Proc: PDBPROCESS): DBINT; {$IFDEF WITH_INLINE}inline; {$ENDIF}
procedure dbfreebuf(Proc: PDBPROCESS); {$IFDEF WITH_INLINE}inline; {$ENDIF}
procedure dbfreequal(Ptr: PAnsiChar); {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbgetchar(Proc: PDBPROCESS; N: Integer): PAnsiChar; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbgetcharset(dbproc: PDBPROCESS): PAnsiChar;{$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbGetRow(dbProc: PDBPROCESS; Row: DBINT): STATUS; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbHasRetStat(dbProc: PDBPROCESS): DBBOOL; {$IFDEF WITH_INLINE}inline; {$ENDIF}
{$ENDIF}
function dbOpen(Login: PLOGINREC; server: PAnsiChar): PDBPROCESS; {$IFDEF WITH_INLINE}inline; {$ENDIF}
{$IFDEF MSWINDOWS}
procedure dbloginfree(loginptr: PLOGINREC); {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbMoreCmds(dbProc: PDBPROCESS): RETCODE; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbname(dbProc: PDBPROCESS): PAnsiChar; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbNextRow(dbProc: PDBPROCESS): STATUS; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbNumCols(dbProc: PDBPROCESS): DBINT; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbResults(dbProc: PDBPROCESS): RETCODE; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbRetData(dbProc: PDBPROCESS; RetNum: Integer): Pointer; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbRetStatus(dbProc: PDBPROCESS): DBINT; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbRetType(dbProc: PDBPROCESS; RetNum: DBINT): DBINT; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbRpcInit(dbProc: PDBPROCESS; RpcName: PAnsiChar; Options: DBSMALLINT): RETCODE; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbRpcParam(dbProc: PDBPROCESS; ParamName: PAnsiChar; Status: Byte;
Type_: DBINT; MaxLen: DBINT; DataLen: DBINT; Value: Pointer): RETCODE; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbRpcSend(dbProc: PDBPROCESS): RETCODE; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbRetLen(dbProc: PDBPROCESS; RetNum: Integer): DBINT; cdecl; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbRetName(dbProc: PDBPROCESS; RetNum: Integer): PAnsiChar; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbSetLoginTime(Seconds: Integer): RETCODE; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbSetLName(Login: PLOGINREC; Value: PAnsiChar; Item: Integer): RETCODE; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbSetMaxprocs(MaxProcs: SmallInt): RETCODE; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbSetTime(Seconds: Integer): RETCODE; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbSetOpt(dbProc: PDBPROCESS; Option: Integer; Char_Param: PAnsiChar; Int_Param: Integer): RETCODE; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbUse(dbProc: PDBPROCESS; dbName: PAnsiChar): RETCODE; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbVaryLen(dbProc: PDBPROCESS; Column: Integer): DBBOOL; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbVersion(): PAnsiChar; {$IFDEF WITH_INLINE}inline; {$ENDIF}
{$ENDIF}
public
{$IFNDEF MSWINDOWS}
dbadata: function(dbproc: PDBPROCESS; ComputeId, Column: Integer): PByte; cdecl;
dbadlen: function(dbproc: PDBPROCESS; ComputeId, Column: Integer): DBINT; cdecl;
dbaltbind: function(dbproc: PDBPROCESS; ComputeId, Column, VarType: Integer;
VarLen: DBINT; VarAddr: PByte): RETCODE; cdecl;
dbaltbind_ps: function(dbproc: PDBPROCESS; ComputeId, Column: Integer; VarType: Integer;
VarLen: DBINT; VarAddr: PByte; typinfo: PDBTYPEINFO): RETCODE; cdecl;
dbaltcolid: function(dbproc: PDBPROCESS; ComputeId, Column: Integer): Integer; cdecl;
dbaltlen: function(dbproc: PDBPROCESS; ComputeId, Column: Integer): DBINT; cdecl;
dbaltop: function(dbproc: PDBPROCESS; ComputeId, Column: Integer): Integer; cdecl;
dbalttype: function(dbproc: PDBPROCESS; ComputeId, Column: Integer): Integer; cdecl;
dbaltutype: function(dbproc: PDBPROCESS; ComputeId, Column: Integer): DBINT; cdecl;
dbanullbind: function(dbproc: PDBPROCESS; ComputeId, Column: Integer; Indicator: PDBINT): RETCODE; cdecl;
dbbind: function(dbproc: PDBPROCESS; Column, VarType, VarLen: Integer; VarAddr: PByte): RETCODE; cdecl;
dbbind_ps: function(dbproc: PDBPROCESS; Column, VarType, VarLen: Integer; VarAddr: PByte; typinfo: PDBTYPEINFO): RETCODE; cdecl;//no MS
dbbufsize: function(dbproc: PDBPROCESS): Integer; cdecl;//no MS
dbbylist: function(dbproc: PDBPROCESS; ComputeId: Integer; Size: PInteger): PByte; cdecl;
dbcancel: function(dbproc: PDBPROCESS): RETCODE; cdecl;
dbcanquery: function(dbproc: PDBPROCESS): RETCODE; cdecl;
dbchange: function(dbproc: PDBPROCESS): PAnsiChar; cdecl;
dbclose: procedure(dbproc: PDBPROCESS); cdecl;
dbclrbuf: procedure(dbproc: PDBPROCESS; N: DBINT); cdecl;
dbclropt: function(dbproc: PDBPROCESS; Option: Integer; Param: PAnsiChar): RETCODE; cdecl;
dbcmd: function(dbproc: PDBPROCESS; Cmd: PAnsiChar): RETCODE; cdecl;
dbcmdrow: function(dbproc: PDBPROCESS): RETCODE;cdecl;
dbcolbrowse: function(dbproc: PDBPROCESS; Column: Integer): DBBOOL; cdecl;
dbcolinfo: function(pdbhandle: PDBHANDLE; _Type: Integer; Column: DBINT; ComputeId: DBINT; lpdbcol: PDBCOL): RETCODE; cdecl;//no SYB but FreeTDS
dbtablecolinfo: function(pdbhandle: PDBHANDLE; Column: DBINT; lpdbcol: PDBCOL): RETCODE; cdecl;//FreeTDS only!!!
dbcollen: function(dbproc: PDBPROCESS; Column: Integer): DBINT; cdecl;
dbcolname: function(dbproc: PDBPROCESS; Column: Integer): PAnsiChar; cdecl;
dbcolsource: function(dbproc: PDBPROCESS; Column: Integer): PAnsiChar; cdecl;
dbcoltype: function(dbproc: PDBPROCESS; Column: Integer): Integer; cdecl;
dbcolutype: function(dbproc: PDBPROCESS; Column: Integer): DBINT; cdecl;
dbcoltypeinfo: function(dbproc: PDBPROCESS; Column: Integer): PDBTYPEINFO; cdecl;//no MS
dbconvert: function(dbproc: PDBPROCESS; SrcType: Integer; Src: PByte;
SrcLen: DBINT; DestType: Integer; Dest: PByte; DestLen: DBINT): Integer; cdecl;
dbconvert_ps: function(dbproc: PDBPROCESS; SrcType: Integer; Src: PByte;
SrcLen: DBINT; DestType: Integer; Dest: PByte; DestLen: DBINT; typinfo: PDBTYPEINFO): Integer; cdecl;//no MS
dbcount: function(dbproc: PDBPROCESS): DBINT; cdecl;
dbcurcmd: function(dbproc: PDBPROCESS): DBINT; cdecl;
dbcurrow: function(dbproc: PDBPROCESS): DBINT; cdecl;
dbdata: function(dbproc: PDBPROCESS; Column: Integer): PByte; cdecl;
dbdatlen: function(dbproc: PDBPROCESS; Column: Integer): DBINT; cdecl;
dbdead: function(dbproc: PDBPROCESS): DBBOOL; cdecl;
dbexit: procedure; cdecl;
dbHasRetStat: function(dbProc: PDBPROCESS): DBBOOL; cdecl;
dbSqlExec: function(dbProc: PDBPROCESS): RETCODE; cdecl;
dbSqlOk: function(dbProc: PDBPROCESS): RETCODE; cdecl;
dbsqlsend: function(dbProc: PDBPROCESS): RETCODE; cdecl;
//dbfcmd: function(Proc: PDBPROCESS; CmdString: PAnsiChar; var Params): RETCODE; cdecl;
dbfirstrow: function(Proc: PDBPROCESS): DBINT; cdecl;
dbfreebuf: procedure(Proc: PDBPROCESS); cdecl;
dbfreequal: procedure(Ptr: PAnsiChar); cdecl;
dbgetchar: function(Proc: PDBPROCESS; N: Integer): PAnsiChar; cdecl;
dbgetcharset: function(dbproc: PDBPROCESS): PAnsiChar; cdecl;
dbGetRow: function(dbProc: PDBPROCESS; Row: DBINT): STATUS; cdecl;
FdbInit: function: RETCODE; cdecl;
// Jan: renamed this to FdbOpen. I don't know how wo decide between calling
// tdsdbopen and dbopen otherwise.?
FdbOpen: function(Login: PLOGINREC; server: PAnsiChar): PDBPROCESS; cdecl;
FtdsDbOpen: function(Login: PLOGINREC; server: PAnsiChar; msdblib: Integer): PDBPROCESS; cdecl;
dbloginfree: procedure(loginptr: PLOGINREC); cdecl;
dbMoreCmds: function(dbProc: PDBPROCESS): RETCODE; cdecl;
dbname: function(dbProc: PDBPROCESS): PAnsiChar; cdecl;
dbNextRow: function(dbProc: PDBPROCESS): STATUS; cdecl;
dbNumCols: function(dbProc: PDBPROCESS): DBINT; cdecl;
dbResults: function(dbProc: PDBPROCESS): RETCODE; cdecl;
dbRetStatus: function(dbProc: PDBPROCESS): DBINT; cdecl;
dbRpcInit: function(dbProc: PDBPROCESS; RpcName: PAnsiChar; Options: DBSMALLINT): RETCODE; cdecl;
dbRpcParam: function(dbProc: PDBPROCESS; ParamName: PAnsiChar; Status: Byte;
Type_: DBINT; MaxLen: DBINT; DataLen: DBINT; Value: Pointer): RETCODE; cdecl;
dbRpcSend: function(dbProc: PDBPROCESS): RETCODE; cdecl;
dbRetData: function(dbProc: PDBPROCESS; RetNum: Integer): Pointer; cdecl;
dbRetLen: function(dbProc: PDBPROCESS; RetNum: Integer): DBINT; cdecl;
dbRetName: function(dbProc: PDBPROCESS; RetNum: Integer): PAnsiChar; cdecl;
dbRetType: function(dbProc: PDBPROCESS; RetNum: Integer): DBINT; cdecl;
dbSetLoginTime: function(Seconds: Integer): RETCODE; cdecl;
dbSetLName: function(Login: PLOGINREC; Value: PAnsiChar; Item: Integer): RETCODE; cdecl;
dbSetMaxprocs: function(MaxProcs: DBINT): RETCODE; cdecl;
dbSetTime: function(Seconds: DBINT): RETCODE; cdecl;
dbSetOpt: function(dbProc: PDBPROCESS; Option: Integer; Char_Param: PAnsiChar; Int_Param: Integer): RETCODE; cdecl;
dbUse: function(dbProc: PDBPROCESS; dbName: PAnsiChar): RETCODE; cdecl;
dbvarylen: function(Proc: PDBPROCESS; Column: Integer): DBBOOL; cdecl;
dbversion: function: PAnsiChar; cdecl;
{$ENDIF}
public { macros }
function dbSetLApp(Login: PLOGINREC; AppName: PAnsiChar): RETCODE; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbSetLHost(Login: PLOGINREC; HostName: PAnsiChar): RETCODE; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbSetLCharSet(Login: PLOGINREC; CharsetName: PAnsiChar): RETCODE; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbSetLNatLang(Login: PLOGINREC; NatLangName: PAnsiChar): RETCODE; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbSetLSecure(Login: PLOGINREC): RETCODE; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbSetLPacket(Login: PLOGINREC; packet_size: Word): RETCODE; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbSetLPwd(Login: PLOGINREC; Password: PAnsiChar): RETCODE; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbSetLUser(Login: PLOGINREC; UserName: PAnsiChar): RETCODE; {$IFDEF WITH_INLINE}inline; {$ENDIF}
public { incompatibility workarounds }
function dbRpcExec(dbProc: PDBPROCESS): RETCODE; {$IFDEF WITH_INLINE}inline; {$ENDIF}
function dbIntit: RETCODE;
function dbsetversion(Version: DBINT): RETCODE;
function dbLogin: PLOGINREC; virtual;
public //mapings from zeos to provider enums
function GetDBOption(AOption: TdbOption): DBINT;
public
{$IFDEF TEST_CALLBACK}
function GetErrorHandler(dbProc: PDBPROCESS; ADBERRHANDLE_PROC: TDBERRHANDLE_PROC): IZDBLibErrorHandler;
function GetMessageHandler(dbProc: PDBPROCESS; ADBMSGHANDLE_PROC: TDBMSGHANDLE_PROC): IZDBLibMessageHandler;
procedure DeRegisterErrorHandler(Const Handler: TDbLibErrorHandler);
procedure DeRegisterMessageHandler(Const Handler: TDbLibMessageHandler);
{$ELSE}
procedure AssignErrorMessages(dbProc: PDBPROCESS; DestErrors: TZDBLibErrorList; DestMessages: TZDBLibMessageList);
{$ENDIF TEST_CALLBACK}
public
property DBLibraryVendorType: TDBLibraryVendorType read fDBLibraryVendorType;
end;
TMSSQLDBLibPLainDriver = class(TZDBLIBPLainDriver, IZPlainDriver)
protected
procedure LoadCodePages; override;
function Clone: IZPlainDriver; override;
public
procedure AfterConstruction; override;
function GetProtocol: string; override;
function GetDescription: string; override;
end;
TSybaseDBLibPLainDriver = class(TZDBLIBPLainDriver, IZPlainDriver)
protected
procedure LoadCodePages; override;
function Clone: IZPlainDriver; override;
procedure LoadApi; override;
public
procedure AfterConstruction; override;
function GetProtocol: string; override;
function GetDescription: string; override;
end;
{$IFDEF TEST_CALLBACK}
//see: https://www.experts-exchange.com/questions/10414716/How-to-make-a-Callback-Procedure-Function-to-Procedure-Function-of-Object.html
//http://delphi.cjcsoft.net/viewthread.php?tid=45566
//https://entwickler-forum.de/forum/archiv/andere-sprachen-aa/delphi-aa/dll/25575-objekte-aus-callback-funktionen-ansprechen
TZMethodToDllCallbackProcedure = class(TZMethodToDllCallbackDispatcher)
private
{$IFDEF AUTOREFCOUNT}[weak]{$ENDIF}FManager: TZDBLIBPLainDriver;
public
constructor Create(const Instance: TObject; methodAddr: pointer;
const CallBackManager: TZDBLIBPLainDriver);
end;
TDbLibErrorHandler = class(TZMethodToDllCallbackProcedure, IZDBLibErrorHandler)
private
FHandle: PDBPROCESS;
{$IFDEF MSWINDOWS}
FOlddberrhandle_stdcall: TDBERRHANDLE_PROC_stdcall;
{$ENDIF MSWINDOWS}
FOlddberrhandle_cdecl: TDBERRHANDLE_PROC_cdecl;
FMydberrhandle: TDBERRHANDLE_PROC; //fastcall convention
{$IFDEF MSWINDOWS}
function dberrhandle_stdcall(Proc: PDBPROCESS; Severity, DbErr, OsErr: Integer;
DbErrStr, OsErrStr: PAnsiChar): Integer; stdcall;
{$ENDIF MSWINDOWS}
function dberrhandle_cdecl(Proc: PDBPROCESS; Severity, DbErr, OsErr: Integer;
DbErrStr, OsErrStr: PAnsiChar): Integer; cdecl;
public
Constructor Create(Handle: PDBPROCESS; DBERRHANDLE_PROC: TDBERRHANDLE_PROC;
const Manager: TZDBLIBPLainDriver);
procedure BeforeDestruction; override;
end;
TDbLibMessageHandler = class(TZMethodToDllCallbackProcedure, IZDBLibMessageHandler)
private
FHandle: PDBPROCESS;
{$IFDEF MSWINDOWS}
FOlddbmsghandle_stdcall: TDBMSGHANDLE_PROC_stdcall;
{$ENDIF MSWINDOWS}
FOlddbmsghandle_cdecl: TDBMSGHANDLE_PROC_cdecl;
FMydbmsghandle: TDBMSGHANDLE_PROC; //fastcall convention
{$IFDEF MSWINDOWS}
function dbmsghandle_stdcall(Proc: PDBPROCESS; MsgNo: DBINT; MsgState, Severity: Integer;
MsgText, SrvName, ProcName: PAnsiChar; Line: DBUSMALLINT): Integer; stdcall;
{$ENDIF MSWINDOWS}
function dbmsghandle_cdecl(Proc: PDBPROCESS; MsgNo: DBINT; MsgState, Severity: Integer;
MsgText, SrvName, ProcName: PAnsiChar; Line: DBUSMALLINT): Integer; cdecl;
public
Constructor Create(Handle: PDBPROCESS; DBMSGHANDLE_PROC: TDBMSGHANDLE_PROC;
const Manager: TZDBLIBPLainDriver);
procedure BeforeDestruction; override;
end;
{$ENDIF TEST_CALLBACK}
function TdsDateTimeAllGetPrecision(const Value: TDBDATETIMEALL): Integer;
function TdsDateTimeAllHasDate(const Value: TDBDATETIMEALL): Boolean;
function TdsDateTimeAllHasTime(const Value: TDBDATETIMEALL): Boolean;
function TdsDateTimeAllHasOffset(const Value: TDBDATETIMEALL): Boolean;
{$ENDIF ZEOS_DISABLE_DBLIB}
implementation
{$IFNDEF ZEOS_DISABLE_DBLIB}
uses SysUtils, ZPlainLoader, ZEncoding, ZFastCode;
var
OldFreeTDSErrorHandle: TDBERRHANDLE_PROC_cdecl = nil;
OldFreeTDSMessageHandle: TDBMSGHANDLE_PROC_cdecl = nil;
OldSybaseErrorHandle: {$IFDEF MSWINDOWS}TDBERRHANDLE_PROC_stdcall{$ELSE}TDBERRHANDLE_PROC_cdecl{$ENDIF} = nil;
OldSybaseMessageHandle: {$IFDEF MSWINDOWS}TDBMSGHANDLE_PROC_stdcall{$ELSE}TDBMSGHANDLE_PROC_cdecl{$ENDIF} = nil;
{$IFDEF MSWINDOWS}
OldMsSQLErrorHandle: TDBERRHANDLE_PROC_cdecl = nil;
OldMsSQLMessageHandle: TDBMSGHANDLE_PROC_cdecl = nil;
{$ENDIF MSWINDOWS}
ErrorCS: TCriticalSection;
SQLErrors: TZDBLibErrorList;
SQLMessages: TZDBLibMessageList;
procedure AddSybaseCodePages(PlainDriver: TZAbstractPlainDriver);
begin
// codepages as found in "SAP Adaptive Server Enterprise 16.0 > Configuration Guide for UNIX Adaptive Server Enterprise 16.0 > Localization Support"
PlainDriver.AddCodePage('ascii_8', 1, ceAnsi, zCP_us_ascii);
PlainDriver.AddCodePage('big5', 2, ceAnsi, zCP_Big5);
PlainDriver.AddCodePage('cp437', 3, ceAnsi, zCP_DOS437);
PlainDriver.AddCodePage('cp850', 4, ceAnsi, zCP_DOS850);
PlainDriver.AddCodePage('cp852', 5, ceAnsi, zCP_DOS852);
PlainDriver.AddCodePage('cp855', 6, ceAnsi, zCP_DOS855);
PlainDriver.AddCodePage('cp857', 7, ceAnsi, zCP_DOS857);
PlainDriver.AddCodePage('cp858', 8, ceAnsi, zCP_DOS858);
PlainDriver.AddCodePage('cp860', 9, ceAnsi, zCP_DOS860);
PlainDriver.AddCodePage('cp864', 10, ceAnsi, zCP_DOS864);
PlainDriver.AddCodePage('cp866', 11, ceAnsi, zCP_DOS866);
PlainDriver.AddCodePage('cp869', 12, ceAnsi, zCP_DOS869);
PlainDriver.AddCodePage('cp874', 13, ceAnsi, zCP_WIN874);
PlainDriver.AddCodePage('cp932', 14, ceAnsi, zCP_SHIFTJS);
PlainDriver.AddCodePage('cp936', 15, ceAnsi, zCP_GB2312);
PlainDriver.AddCodePage('cp950', 16, ceAnsi, zCP_Big5);
PlainDriver.AddCodePage('cp1250', 17, ceAnsi, zCP_WIN1250);
PlainDriver.AddCodePage('cp1251', 18, ceAnsi, zCP_WIN1251);
PlainDriver.AddCodePage('cp1252', 19, ceAnsi, zCP_WIN1252);
PlainDriver.AddCodePage('cp1253', 20, ceAnsi, zCP_WIN1253);
PlainDriver.AddCodePage('cp1254', 21, ceAnsi, zCP_WIN1254);
PlainDriver.AddCodePage('cp1255', 22, ceAnsi, zCP_WIN1255);
PlainDriver.AddCodePage('cp1256', 23, ceAnsi, zCP_WIN1256);
PlainDriver.AddCodePage('cp1257', 24, ceAnsi, zCP_WIN1257);
PlainDriver.AddCodePage('cp1258', 25, ceAnsi, zCP_WIN1258);
PlainDriver.AddCodePage('gb18030', 26, ceAnsi, zCP_GB18030);
PlainDriver.AddCodePage('iso_1', 27, ceAnsi, zCP_L1_ISO_8859_1);
PlainDriver.AddCodePage('iso88592', 28, ceAnsi, zCP_L2_ISO_8859_2);
PlainDriver.AddCodePage('iso88595', 29, ceAnsi, zCP_L5_ISO_8859_5);
PlainDriver.AddCodePage('iso88596', 30, ceAnsi, zCP_L6_ISO_8859_6);
PlainDriver.AddCodePage('iso88597', 31, ceAnsi, zCP_L7_ISO_8859_7);
PlainDriver.AddCodePage('iso88598', 32, ceAnsi, zCP_L8_ISO_8859_8);
PlainDriver.AddCodePage('iso88599', 33, ceAnsi, zCP_L5_ISO_8859_9);
PlainDriver.AddCodePage('iso15', 34, ceAnsi, zCP_L9_ISO_8859_15);
PlainDriver.AddCodePage('sjis', 35, ceAnsi, zCP_SHIFTJS);
PlainDriver.AddCodePage('utf8', 36, ceUTF8, zCP_UTF8);
end;
procedure AddmMSCodePages(PlainDriver: TZAbstractPlainDriver);
begin
{ SingleByte }
PlainDriver.AddCodePage('WINDOWS-1250', 1, ceAnsi, zCP_WIN1250, '', 1, False); {Microsoft Windows Codepage 1250 (East European)}
PlainDriver.AddCodePage('WINDOWS-1251', 2, ceAnsi, zCP_WIN1251, '', 1, False); {Microsoft Windows Codepage 1251 (Cyrl)}
PlainDriver.AddCodePage('WINDOWS-1252', 3, ceAnsi, zCP_WIN1252, '', 1, False); {Microsoft Windows Codepage 1252 (ANSI), USASCCI}
PlainDriver.AddCodePage('WINDOWS-1253', 4, ceAnsi, zCP_WIN1253, '', 1, False); {Microsoft Windows Codepage 1253 (Greek)}
PlainDriver.AddCodePage('WINDOWS-1254', 5, ceAnsi, zCP_WIN1254, '', 1, False); {Microsoft Windows Codepage 1254 (Turk)}
PlainDriver.AddCodePage('WINDOWS-1255', 6, ceAnsi, zCP_WIN1255, '', 1, False); {Microsoft Windows Codepage 1255 (Hebrew)}
PlainDriver.AddCodePage('WINDOWS-1256', 7, ceAnsi, zCP_WIN1256, '', 1, False); {Microsoft Windows Codepage 1256 (Arab)}
PlainDriver.AddCodePage('WINDOWS-1257', 8, ceAnsi, zCP_WIN1257, '', 1, False); {Microsoft Windows Codepage 1257 (BaltRim)}
PlainDriver.AddCodePage('WINDOWS-1258', 9, ceAnsi, zCP_WIN1258, '', 1, False); {Microsoft Windows Codepage 1258 (Viet), TCVN-5712}
end;
{ Handle sql server error messages }
function SybaseErrorHandle(dbproc: PDBPROCESS; Severity, DbErr, OsErr: Integer;
DbErrStr, OsErrStr: PAnsiChar): Integer;
{$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};
var
SqlError: PDBLibError;
Index: NativeInt;
begin
ErrorCS.Enter;
try
SqlError := SQLErrors.Add(Index);
SqlError.dbProc := dbproc;
SqlError.Severity := Severity;
SqlError.DbErr := DbErr;
SqlError.OsErr := OsErr;
if DbErrStr <> nil then
ZSetString(DbErrStr, StrLen(DbErrStr), SqlError.DbErrStr);
if OsErrStr <> nil then
ZSetString(OsErrStr, StrLen(OsErrStr), SqlError.OsErrStr);
finally
Result := INT_CANCEL;
ErrorCS.Leave;
end;
end;
{ Handle sql server messages }
function SybaseMessageHandle(dbproc: PDBPROCESS; MsgNo: DBINT; MsgState,
Severity: Integer; MsgText, SrvName, ProcName: PAnsiChar; Line: DBUSMALLINT):
Integer; {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};
var
SQLMessage: PDBLibMessage;
Index: NativeInt;
begin
ErrorCS.Enter;
try
SQLMessage := SQLMessages.Add(Index);
SQLMessage.dbProc := dbproc;
SQLMessage.MsgNo := MsgNo;
SQLMessage.MsgState := MsgState;
SQLMessage.Severity := Severity;
if MsgText <> nil then
ZSetString(MsgText, StrLen(MsgText), SQLMessage.MsgText);
if SrvName <> nil then
ZSetString(SrvName, StrLen(SrvName), SQLMessage.SrvName);
if ProcName <> nil then
ZSetString(ProcName, StrLen(ProcName), SQLMessage.ProcName);
SQLMessage.Line := Line;
finally
Result := 0;
ErrorCS.Leave;
end;
end;
{ Handle sql server error messages }
function DbLibErrorHandle(dbproc: PDBPROCESS; Severity, DbErr, OsErr: Integer;
DbErrStr, OsErrStr: PAnsiChar): Integer; cdecl;
var
SqlError: PDBLibError;
Index: NativeInt;
begin
ErrorCS.Enter;
try
SqlError := SQLErrors.Add(Index);
SqlError.dbProc := dbproc;
SqlError.Severity := Severity;
SqlError.DbErr := DbErr;
SqlError.OsErr := OsErr;
if DbErrStr <> nil then
ZSetString(DbErrStr, StrLen(DbErrStr),SqlError.DbErrStr);
if OsErrStr <> nil then
ZSetString(OsErrStr, StrLen(OsErrStr),SqlError.OsErrStr);
finally
Result := INT_CANCEL;
ErrorCS.Leave;
end;
end;
{ Handle sql server messages }
function DbLibMessageHandle(dbproc: PDBPROCESS; MsgNo: DBINT; MsgState, Severity: Integer;
MsgText, SrvName, ProcName: PAnsiChar; Line: DBUSMALLINT): Integer; cdecl;
var
SQLMessage: PDBLibMessage;
Index: NativeInt;
begin
ErrorCS.Enter;
try
SQLMessage := SQLMessages.Add(Index);
SQLMessage.dbProc := dbproc;
SQLMessage.MsgNo := MsgNo;
SQLMessage.MsgState := MsgState;
SQLMessage.Severity := Severity;
if MsgText <> nil then
ZSetString(MsgText, StrLen(MsgText), SQLMessage.MsgText);
if SrvName <> nil then
ZSetString(SrvName, StrLen(SrvName), SQLMessage.SrvName);
if ProcName <> nil then
ZSetString(ProcName, StrLen(ProcName), SQLMessage.ProcName);
SQLMessage.Line := Line;
finally
Result := 0;
ErrorCS.Leave;
end;
end;
{ Handle sql server error messages }
function FreeTDSErrorHandle(dbproc: PDBPROCESS; Severity, DbErr, OsErr: Integer;
DbErrStr, OsErrStr: PAnsiChar): Integer; cdecl;
var
SqlError: PDBLibError;
Index: NativeInt;
begin
ErrorCS.Enter;
try
SqlError := SQLErrors.Add(Index);
SqlError.dbProc := dbproc;
SqlError.Severity := Severity;
SqlError.DbErr := DbErr;
SqlError.OsErr := OsErr;
if DbErrStr <> nil then
ZSetString(DbErrStr, StrLen(DbErrStr),SqlError.DbErrStr);
if OsErrStr <> nil then
ZSetString(OsErrStr, StrLen(OsErrStr),SqlError.OsErrStr);
finally
Result := INT_CANCEL;
ErrorCS.Leave;
end;
end;
{ Handle sql server messages }
function FreeTDSMessageHandle(dbproc: PDBPROCESS; MsgNo: DBINT; MsgState, Severity: Integer;
MsgText, SrvName, ProcName: PAnsiChar; Line: DBUSMALLINT): Integer; cdecl;
var
SQLMessage: PDBLibMessage;
Index: NativeInt;
begin
ErrorCS.Enter;
try
SQLMessage := SQLMessages.Add(Index);
SQLMessage.dbProc := dbproc;
SQLMessage.MsgNo := MsgNo;
SQLMessage.MsgState := MsgState;
SQLMessage.Severity := Severity;
if MsgText <> nil then
ZSetString(MsgText, StrLen(MsgText), SQLMessage.MsgText);
if SrvName <> nil then
ZSetString(SrvName, StrLen(SrvName), SQLMessage.SrvName);
if ProcName <> nil then
ZSetString(ProcName, StrLen(ProcName), SQLMessage.ProcName);
SQLMessage.Line := Line;
finally
Result := 0;
ErrorCS.Leave;
end;
end;
{ TZDBLIBPLainDriver }
(** Return a pointer to the data for a compute column *)
procedure TZDBLIBPLainDriver.AfterConstruction;
begin
inherited;
FLoader := TZNativeLibraryLoader.Create([]);
{$IFDEF TEST_CALLBACK}
FSQLErrorHandlerList := TZDBLibErrorList.Create;
FSQLMessageHandlerList := TZDBLibMessageList.Create;
FCS := TCriticalSection.Create;
{$ENDIF}
FLoader.AddLocation('sybdb'+SharedSuffix);
LoadCodePages;
end;
{$IFDEF TEST_CALLBACK}
procedure TZDBLIBPLainDriver.BeforeDestruction;
var I: Integer;
begin
inherited;
for i := FSQLErrorHandlerList.Count-1 downto 0 do
Dispose(PDBLibError(FSQLErrorHandlerList[i]));
FreeAndNil(FSQLErrorHandlerList);
for i := FSQLMessageHandlerList.Count-1 downto 0 do
Dispose(PDBLibMessage(FSQLMessageHandlerList[i]));
FreeAndNil(FSQLMessageHandlerList);
FCS.Free;
end;
{$ELSE TEST_CALLBACK}
procedure TZDBLIBPLainDriver.AssignErrorMessages(dbProc: PDBPROCESS;
DestErrors: TZDBLibErrorList; DestMessages: TZDBLibMessageList);
var I: Integer;
Src, Dest: Pointer;
Index: NativeInt;
begin
ErrorCS.Enter;
try
for i := SQLErrors.Count -1 downto 0 do
if (dbProc = nil) or (PDBLibError(SQLErrors[i]).dbProc = dbProc) then begin
Dest := DestErrors.Add(Index);
Src := SQLErrors[i];
Move(Src^, Dest^, SizeOf(TDBLibError));
FillChar(Src^, SizeOf(TDBLibError), #0);
SQLErrors.Delete(i);
end;
for i := SQLMessages.Count -1 downto 0 do
if (dbProc = nil) or (PDBLibMessage(SQLMessages[i]).dbProc = dbProc) then begin
Dest := DestMessages.Add(Index);
Src := SQLMessages[i];
Move(Src^, Dest^, SizeOf(TDBLibMessage));
FillChar(Src^, SizeOf(TDBLibMessage), #0);
SQLMessages.Delete(i);
end;
finally
ErrorCS.Leave;
end;
end;
{$ENDIF TEST_CALLBACK}
{$IFDEF MSWINDOWS}
function TZDBLIBPLainDriver.dbadata(dbproc: PDBPROCESS; ComputeId,
Column: Integer): PByte;
begin
if Assigned(Fdbadata)
then Result := Fdbadata(dbproc, ComputeID, Column)
else Result := Fdbadata_stdcall(dbproc, ComputeID, Column)
end;
(** Return the actual length of the data for a compute column *)
function TZDBLIBPLainDriver.dbadlen(dbproc: PDBPROCESS; ComputeId,
Column: Integer): DBINT;
begin
if Assigned(Fdbadlen)
then Result := Fdbadlen(dbproc, ComputeID, Column)
else Result := Fdbadlen_stdcall(dbproc, ComputeID, Column);
end;
(** Bind a compute column to a program variable *)
function TZDBLIBPLainDriver.dbaltbind(dbproc: PDBPROCESS; ComputeId,
Column, VarType: Integer; VarLen: DBINT; VarAddr: PByte): RETCODE;
begin
if Assigned(Fdbaltbind)
then Result := Fdbaltbind(dbproc, ComputeID, Column, VarType, VarLen, VarAddr)
else Result := Fdbaltbind_stdcall(dbproc, ComputeID, Column, VarType, VarLen, VarAddr)
end;
(** Bind a compute column to a program variable,
with precision and scale support for numeric and decimal datatypes *)
function TZDBLIBPLainDriver.dbaltbind_ps(dbproc: PDBPROCESS; ComputeId,
Column, VarType: Integer; VarLen: DBINT; VarAddr: PByte;
typinfo: PDBTYPEINFO): RETCODE;
begin
if Assigned(Fdbaltbind_ps)
then Result := Fdbaltbind_ps(dbproc, ComputeID, Column, VarType, VarLen, VarAddr, typinfo)
else Result := Fdbaltbind_ps_stdcall(dbproc, ComputeID, Column, VarType, VarLen, VarAddr, typinfo)
end;
(** Return the column ID for a compute column *)
function TZDBLIBPLainDriver.dbaltcolid(dbproc: PDBPROCESS; ComputeId,
Column: Integer): Integer;
begin
if Assigned(Fdbaltcolid)
then Result := Fdbaltcolid(dbproc, ComputeID, Column)
else Result := Fdbaltcolid_stdcall(dbproc, ComputeID, Column)
end;
(** Return the maximum length of the data for a particular compute column *)
function TZDBLIBPLainDriver.dbaltlen(dbproc: PDBPROCESS; ComputeId,
Column: Integer): DBINT;
begin
if Assigned(Fdbaltlen)
then Result := Fdbaltlen(dbproc, ComputeID, Column)
else Result := Fdbaltlen_stdcall(dbproc, ComputeID, Column)
end;
(** Return the type of aggregate operator for a particular compute column *)
function TZDBLIBPLainDriver.dbaltop(dbproc: PDBPROCESS; ComputeId,
Column: Integer): Integer;
begin
if Assigned(Fdbaltop)
then Result := Fdbaltop(dbproc, ComputeID, Column)
else Result := Fdbaltop_stdcall(dbproc, ComputeID, Column)
end;
(** Return the datatype for a compute column *)
function TZDBLIBPLainDriver.dbalttype(dbproc: PDBPROCESS; ComputeId,
Column: Integer): Integer;
begin
if Assigned(Fdbalttype)
then Result := Fdbalttype(dbproc, ComputeID, Column)
else Result := Fdbalttype_stdcall(dbproc, ComputeID, Column)
end;
(** Return the user-defined datatype for a compute column *)
function TZDBLIBPLainDriver.dbaltutype(dbproc: PDBPROCESS; ComputeId,
Column: Integer): DBINT;
begin
if Assigned(Fdbaltutype)
then Result := Fdbaltutype(dbproc, ComputeID, Column)
else Result := Fdbaltutype_stdcall(dbproc, ComputeID, Column)
end;
(** Associate an indicator variable with a compute-row column *)
function TZDBLIBPLainDriver.dbanullbind(dbproc: PDBPROCESS; ComputeId,
Column: Integer; Indicator: PDBINT): RETCODE;
begin
if Assigned(Fdbanullbind)
then Result := Fdbanullbind(dbproc, ComputeID, Column, Indicator)
else Result := Fdbanullbind_stdcall(dbproc, ComputeID, Column, Indicator)
end;
(** Bind a regular result column to a program variable *)
function TZDBLIBPLainDriver.dbbind(dbproc: PDBPROCESS; Column, VarType,
VarLen: Integer; VarAddr: PByte): RETCODE;
begin
if Assigned(Fdbbind)
then Result := Fdbbind(dbproc, Column, VarType, VarLen, VarAddr)
else Result := Fdbbind_stdcall(dbproc, Column, VarType, VarLen, VarAddr)
end;
(** Bind a regular result column to a program variable,
with precision and scale support for numeric and decimal datatypes *)
function TZDBLIBPLainDriver.dbbind_ps(dbproc: PDBPROCESS; Column,
VarType, VarLen: Integer; VarAddr: PByte; typinfo: PDBTYPEINFO): RETCODE;
begin
if Assigned(Fdbbind_ps)
then Result := Fdbbind_ps(dbproc, Column, VarType, VarLen, VarAddr, typinfo)
else Result := Fdbbind_ps_stdcall(dbproc, Column, VarType, VarLen, VarAddr, typinfo)
end;
(** Return the size of a DBPROCESS row buffer *)
function TZDBLIBPLainDriver.dbbufsize(dbproc: PDBPROCESS): Integer;
begin
if Assigned(Fdbbufsize)
then Result := Fdbbufsize(dbproc)
else Result := Fdbbufsize_stdcall(dbproc)
end;
(** Return the bylist for a compute row *)
function TZDBLIBPLainDriver.dbbylist(dbproc: PDBPROCESS;
ComputeId: Integer; Size: PInteger): PByte;
begin
if Assigned(Fdbbylist)
then Result := Fdbbylist(dbproc, ComputeId, Size)
else Result := Fdbbylist_stdcall(dbproc, ComputeId, Size)
end;
(** Cancel the current command batch *)
function TZDBLIBPLainDriver.dbcancel(dbproc: PDBPROCESS): RETCODE;
begin
if Assigned(Fdbcancel)
then Result := Fdbcancel(dbproc)
else Result := Fdbcancel_stdcall(dbproc)
end;
(** Cancel any rows pending from the most recently executed query *)
function TZDBLIBPLainDriver.dbcanquery(dbproc: PDBPROCESS): RETCODE;
begin
if Assigned(Fdbcanquery)
then Result := Fdbcanquery(dbproc)
else Result := Fdbcanquery_stdcall(dbproc)
end;
(** Determine whether a command batch has changed the current database *)
function TZDBLIBPLainDriver.dbchange(dbproc: PDBPROCESS): PAnsiChar;
begin
if Assigned(Fdbchange)
then Result := Fdbchange(dbproc)
else Result := Fdbchange_stdcall(dbproc)
end;
(** Close and deallocate a single DBPROCESS structure *)
procedure TZDBLIBPLainDriver.dbclose(dbproc: PDBPROCESS);
begin
if Assigned(Fdbclose_ms) then
Fdbclose_ms(dbproc)
else if Assigned(Fdbclose_stdcall) then
Fdbclose_stdcall(dbproc)
else Fdbclose_SYB(dbproc);
end;
(** Drop rows from the row buffer *)
procedure TZDBLIBPLainDriver.dbclrbuf(dbproc: PDBPROCESS; N: DBINT);
begin
if Assigned(Fdbclrbuf)
then Fdbclrbuf(dbproc, N)
else Fdbclrbuf_stdcall(dbproc, n)
end;
(** Clear an option set by dbsetopt *)
function TZDBLIBPLainDriver.dbclropt(dbproc: PDBPROCESS; Option: Integer;
Param: PAnsiChar): RETCODE;
begin
if Assigned(Fdbclropt)
then Result := Fdbclropt(dbproc, Option, Param)
else Result := Fdbclropt_stdcall(dbproc, Option, Param)
end;
(** Add text to the DBPROCESS command buffer *)
function TZDBLIBPLainDriver.dbcmd(dbproc: PDBPROCESS;
Cmd: PAnsiChar): RETCODE;
begin
if Assigned(Fdbcmd)
then Result := Fdbcmd(dbproc, Cmd)
else Result := Fdbcmd_stdcall(dbproc, Cmd)
end;
(** Determine whether the current command can return rows *)
function TZDBLIBPLainDriver.dbcmdrow(dbproc: PDBPROCESS): RETCODE;
begin
if Assigned(Fdbcmdrow)
then Result := Fdbcmdrow(dbproc)
else Result := Fdbcmdrow_stdcall(dbproc)
end;
(** Determine whether the source of a regular result column is updatable
through the DB-Library browse-mode facilities *)
function TZDBLIBPLainDriver.dbcolbrowse(dbproc: PDBPROCESS;
Column: Integer): DBBOOL;
begin
if Assigned(Fdbcolbrowse_SYB) then
Result := Fdbcolbrowse_SYB(dbproc, Column)
else if Assigned(Fdbcolbrowse_MS) then
Result := Ord(Fdbcolbrowse_MS(dbproc, Column))
else
Result := Fdbcolbrowse_stdcall(dbproc, Column)
end;
(** Return the maximum length of the data in a regular result column *)
function TZDBLIBPLainDriver.dbcollen(dbproc: PDBPROCESS;
Column: Integer): DBINT;
begin
if Assigned(Fdbcollen)
then Result := Fdbcollen(dbproc, Column)
else Result := Fdbcollen_stdcall(dbproc, Column)
end;
(** Return the name of a regular result column *)
function TZDBLIBPLainDriver.dbcolname(dbproc: PDBPROCESS;
Column: Integer): PAnsiChar;
begin
if Assigned(Fdbcolname)
then Result := Fdbcolname(dbproc, Column)
else Result := Fdbcolname_stdcall(dbproc, Column)
end;
(** Return a pointer to the name of the database column from which the
specified regular result column was derived *)
function TZDBLIBPLainDriver.dbcolsource(dbproc: PDBPROCESS;
Column: Integer): PAnsiChar;
begin
if Assigned(Fdbcolsource)
then Result := Fdbcolsource(dbproc, Column)
else Result := Fdbcolsource_stdcall(dbproc, Column)
end;
(** Return the datatype for a regular result column *)
function TZDBLIBPLainDriver.dbcoltype(dbproc: PDBPROCESS;
Column: Integer): Integer;
begin
if Assigned(Fdbcoltype)
then Result := Fdbcoltype(dbproc, Column)
else Result := Fdbcoltype_stdcall(dbproc, Column)
end;
(** Return precision and scale information for a regular
result column of type numeric or decimal. *)
function TZDBLIBPLainDriver.dbcoltypeinfo(dbproc: PDBPROCESS;
Column: Integer): PDBTYPEINFO;
begin
if Assigned(Fdbcoltypeinfo)
then Result := Fdbcoltypeinfo(dbproc, Column)
else Result := Fdbcoltypeinfo_stdcall(dbproc, Column)
end;
(** Return the user-defined datatype for a regular result column *)
function TZDBLIBPLainDriver.dbcolutype(dbproc: PDBPROCESS;
Column: Integer): DBINT;
begin
if Assigned(Fdbcolutype)
then Result := Fdbcolutype(dbproc, Column)
else Result := Fdbcolutype_stdcall(dbproc, Column)
end;
(** Convert data from one datatype to another *)
function TZDBLIBPLainDriver.dbconvert(dbproc: PDBPROCESS; SrcType: Integer;
Src: PByte; SrcLen: DBINT; DestType: Integer; Dest: PByte;
DestLen: DBINT): Integer;
begin
if Assigned(Fdbconvert)
then Result := Fdbconvert(dbproc, SrcType, Src, SrcLen, DestType, Dest, DestLen)
else Result := Fdbconvert_stdcall(dbproc, SrcType, Src, SrcLen, DestType, Dest, DestLen)
end;
(** Convert data from one datatype to another, with precision and scale
support for numeric and decimal datatypes *)
function TZDBLIBPLainDriver.dbconvert_ps(dbproc: PDBPROCESS;
SrcType: Integer; Src: PByte; SrcLen: DBINT; DestType: Integer; Dest: PByte;
DestLen: DBINT; typinfo: PDBTYPEINFO): Integer;
begin
if Assigned(Fdbconvert_ps)
then Result := Fdbconvert_ps(dbproc, SrcType, Src, SrcLen, DestType, Dest, DestLen, typinfo)
else Result := Fdbconvert_ps_stdcall(dbproc, SrcType, Src, SrcLen, DestType, Dest, DestLen, typinfo)
end;
(** Returns the number of rows affected by a Transact-SQL command *)
function TZDBLIBPLainDriver.dbcount(dbproc: PDBPROCESS): DBINT;
begin
if Assigned(Fdbcount)
then Result := Fdbcount(dbproc)
else Result := Fdbcount_stdcall(dbproc);
end;
(** Return the number of the current command *)
function TZDBLIBPLainDriver.dbcurcmd(dbproc: PDBPROCESS): DBINT;
begin
if Assigned(Fdbcurcmd_SYB) then
Result := Fdbcurcmd_SYB(dbproc)
else if Assigned(Fdbcurcmd_MS) then
Result := Fdbcurcmd_MS(dbproc)
else Result := Fdbcurcmd_stdcall(dbproc)
end;
(** Return the number of the row currently being read *)
function TZDBLIBPLainDriver.dbcurrow(dbproc: PDBPROCESS): DBINT;
begin
if Assigned(Fdbcurrow)
then Result := Fdbcurrow(dbproc)
else Result := Fdbcurrow_stdcall(dbproc)
end;
(** Return a pointer to the data in a regular result column *)
function TZDBLIBPLainDriver.dbdata(dbproc: PDBPROCESS;
Column: Integer): PByte;
begin
if Assigned(Fdbdata)
then Result := Fdbdata(dbproc, Column)
else Result := Fdbdata_stdcall(dbproc, Column)
end;
(** Return the length of the data in a regular result column *)
function TZDBLIBPLainDriver.dbdatlen(dbproc: PDBPROCESS;
Column: Integer): DBINT;
begin
if Assigned(Fdbdatlen)
then Result := Fdbdatlen(dbproc, Column)
else Result := Fdbdatlen_stdcall(dbproc, Column)
end;
(** Determine whether a particular DBPROCESS is dead *)
function TZDBLIBPLainDriver.dbdead(dbproc: PDBPROCESS): DBBOOL;
begin
if Assigned(Fdbdead)
then Result := Fdbdead(dbproc)
else if Assigned(Fdbdead_MS)
then Result := Ord(Fdbdead_MS(dbproc))
else Result := Fdbdead_stdcall(dbproc);
end;
(** Close and deallocate all DBPROCESS structures,
and clean up any structures initialized by dbinit. *)
procedure TZDBLIBPLainDriver.dbexit;
begin
if Assigned(Fdbexit)
then Fdbexit
else Fdbexit_stdcall;
end;
(** Return the number of the first row in the row buffer *)
function TZDBLIBPLainDriver.dbfirstrow(Proc: PDBPROCESS): DBINT;
begin
if Assigned(Fdbfirstrow)
then Result := Fdbfirstrow(Proc)
else Result := Fdbfirstrow_stdcall(Proc);
end;
(** Clear the command buffer *)
procedure TZDBLIBPLainDriver.dbfreebuf(Proc: PDBPROCESS);
begin
if Assigned(Fdbfreebuf)
then Fdbfreebuf(Proc)
else Fdbfreebuf_stdcall(Proc);
end;
(** Free the memory allocated by dbqual *)
procedure TZDBLIBPLainDriver.dbfreequal(Ptr: PAnsiChar);
begin
if Assigned(Fdbfreequal)
then Fdbfreequal(Ptr)
else Fdbfreequal_stdcall(Ptr);
end;
(** Return a pointer to a character in the command buffer. *)
function TZDBLIBPLainDriver.dbgetchar(Proc: PDBPROCESS;
N: Integer): PAnsiChar;
begin
if Assigned(Fdbgetchar)
then Result := Fdbgetchar(Proc, N)
else Result := Fdbgetchar_stdcall(Proc, N);
end;
(** Get the name of the client character set from the DBPROCESS structure *)
function TZDBLIBPLainDriver.dbgetcharset(dbproc: PDBPROCESS): PAnsiChar;
begin
if Assigned(Fdbgetcharset)
then Result := Fdbgetcharset(dbproc)
else Result := Fdbgetcharset_stdcall(dbproc);
end;
{** Read the specified row in the row buffer. *}
function TZDBLIBPLainDriver.dbGetRow(dbProc: PDBPROCESS; Row: DBINT): STATUS;
begin
if Assigned(FdbGetRow)
then Result := FdbGetRow(dbproc, Row)
else Result := FdbGetRow_stdcall(dbproc, Row);
end;
{** Determine whether the current command or remote procedure call
generated a return status number. *}
function TZDBLIBPLainDriver.dbHasRetStat(dbProc: PDBPROCESS): DBBOOL;
begin
if Assigned(FdbHasRetStat_MS)
then Result := Ord(FdbHasRetStat_MS(dbproc))
else if Assigned(FdbHasRetStat_SYB)
then Result := FdbHasRetStat_SYB(dbproc)
else Result := FdbHasRetStat_stdcall(dbproc);
end;
{$ENDIF MSWINDOWS}
{** Initialize DB-Library. }
function TZDBLIBPLainDriver.dbIntit: RETCODE;
{$IFDEF MSWINDOWS}var P: PAnsiChar;{$ENDIF}
begin
{$IFDEF MSWINDOWS}
if Assigned(FdbInit_MS) then begin
P := FdbInit_MS;
if P <> nil then begin
Result := DBSUCCEED;
{$IFDEF UNICODE}
FClientVersion := ZEncoding.PRawToUnicode(P, StrLen(P), zCP_us_ascii);
{$ELSE}
SetString(FClientVersion, P, StrLen(P));
{$ENDIF}
end else Result := DBFail
end else if Assigned(FdbInit)
then Result := FdbInit
else Result := FdbInit_stdcall;
{$ELSE MSWINDOWS}
Result := FdbInit;
{$ENDIF MSWINDOWS}
end;
{** Allocates a login record for use in dbopen *}
function TZDBLIBPLainDriver.dbLogin: PLOGINREC;
begin
{$IFDEF MSWINDOWS}
if Assigned(FdbLogin)
then Result := FdbLogin
else Result := FdbLogin_stdcall;
{$ELSE}
Result := FdbLogin;
{$ENDIF}
end;
{$IFDEF MSWINDOWS}
{** Free a login record *}
procedure TZDBLIBPLainDriver.dbloginfree(loginptr: PLOGINREC);
begin
if Assigned(Fdbloginfree)
then Fdbloginfree(loginptr)
else FdbLoginfree_stdcall(loginptr);
end;
{** Indicate whether there are more commands to be processed. *}
function TZDBLIBPLainDriver.dbMoreCmds(dbProc: PDBPROCESS): RETCODE;
begin
if Assigned(FdbMoreCmds)
then Result := FdbMoreCmds(dbProc)
else Result := FdbMoreCmds_stdcall(dbProc);
end;
{** Return the name of the current database. *}
function TZDBLIBPLainDriver.dbname(dbProc: PDBPROCESS): PAnsiChar;
begin
if Assigned(Fdbname)
then Result := Fdbname(dbProc)
else Result := Fdbname_stdcall(dbProc);
end;
{** Read the next result row into the row buffer and into any program variables
that are bound to column data *}
function TZDBLIBPLainDriver.dbNextRow(dbProc: PDBPROCESS): STATUS;
begin
if Assigned(FdbNextRow)
then Result := FdbNextRow(dbProc)
else Result := FdbNextRow_stdcall(dbProc);
end;
{** Determine the number of regular columns for the current set of results *}
function TZDBLIBPLainDriver.dbNumCols(dbProc: PDBPROCESS): DBINT;
begin
if Assigned(FdbNumCols)
then Result := FdbNumCols(dbProc)
else Result := FdbNumCols_stdcall(dbProc);
end;
{$ENDIF}
{** Create and initialize a DBPROCESS structure. *}
function TZDBLIBPLainDriver.dbOpen(Login: PLOGINREC;
server: PAnsiChar): PDBPROCESS;
begin
if Assigned(FTdsDbOpen) then
// the ORD() thing is strange. It makes dblib terminate the program if no
// correct login information is given. This made the test TZTestConnectionCase.TestLoginPromptConnection
// fail when trying to login using 'x' as the user name. When reverting to 1,
// everything works as expected.
Result := FTdsDbOpen(Login, server, 1{Ord(ZFastCode.Pos('Sybase', GetDescription) > 0)})
else
{$IFNDEF MSWINDOWS}
Result := FdbOpen(Login, server);
{$ELSE}
if Assigned(FdbOpen)
then Result := FdbOpen(Login, server)
else Result := FdbOpen_stdcall(Login, server)
{$ENDIF}
end;
{$IFDEF MSWINDOWS}
{** Set up the results of the next query. *}
function TZDBLIBPLainDriver.dbResults(dbProc: PDBPROCESS): RETCODE;
begin
if Assigned(FdbResults)
then Result := FdbResults(dbProc)
else Result := FdbResults_stdcall(dbProc);
end;
{** Return a pointer to a return parameter value generated by a stored procedure. *}
function TZDBLIBPLainDriver.dbRetData(dbProc: PDBPROCESS;
RetNum: Integer): Pointer;
begin
if Assigned(FdbRetData)
then Result := FdbRetData(dbProc, RetNum)
else Result := FdbRetData_stdcall(dbProc, RetNum);
end;
{** Determine the length of a return parameter value
generated by a stored procedure. *}
function TZDBLIBPLainDriver.dbRetLen(dbProc: PDBPROCESS;
RetNum: Integer): DBINT;
begin
if Assigned(FdbRetLen)
then Result := FdbRetLen(dbProc, RetNum)
else Result := FdbRetLen_stdcall(dbProc, RetNum);
end;
{** Determine the name of the stored procedure parameter
associated with a particular return parameter value. *}
function TZDBLIBPLainDriver.dbRetName(dbProc: PDBPROCESS;
RetNum: Integer): PAnsiChar;
begin
if Assigned(FdbRetName)
then Result := FdbRetName(dbProc, RetNum)
else Result := FdbRetName_stdcall(dbProc, RetNum);
end;
{** Determine the stored procedure status number returned by the
current command or remote procedure call. *}
function TZDBLIBPLainDriver.dbRetStatus(dbProc: PDBPROCESS): DBINT;
begin
if Assigned(FdbRetStatus)
then Result := FdbRetStatus(dbProc)
else Result := FdbRetStatus_stdcall(dbProc);
end;
{** Determine the datatype of a return parameter value
generated by a stored procedure. *}
function TZDBLIBPLainDriver.dbRetType(dbProc: PDBPROCESS; RetNum: DBINT): DBINT;
begin
if Assigned(FdbRetType)
then Result := FdbRetType(dbProc, RetNum)
else Result := FdbRetType_stdcall(dbProc, RetNum);
end;
{$ENDIF MSWINDOWS}
{** emmidate exceute the remote procedure call. *}
function TZDBLIBPLainDriver.dbRpcExec(dbProc: PDBPROCESS): RETCODE;
begin
{$IFDEF MSWINDOWS}
if Assigned(FdbRpcExec)
then Result := FdbRpcExec(dbProc)
else if Assigned(FdbRpcSend) then begin
Result := FdbRpcSend(dbProc);
if Result = SUCCEED then
Result := dbSqlOk(dbProc);
end else begin
Result := FdbRpcSend_stdCall(dbProc);
if Result = SUCCEED then
Result := FdbSqlOk_stdcall(dbProc);
end;
{$ELSE}
Result := dbRpcExec(dbProc);
if Result = SUCCEED then
Result := dbSqlOk(dbProc);
{$ENDIF}
end;
{$IFDEF MSWINDOWS}
{** Initialize a remote procedure call *}
function TZDBLIBPLainDriver.dbRpcInit(dbProc: PDBPROCESS; RpcName: PAnsiChar;
Options: DBSMALLINT): RETCODE;
begin
if Assigned(FdbRpcInit)
then Result := FdbRpcInit(dbProc, RpcName, Options)
else Result := FdbRpcInit_stdcall(dbProc, RpcName, Options);
end;
{** Add a parameter to a remote procedure call. *}
function TZDBLIBPLainDriver.dbRpcParam(dbProc: PDBPROCESS; ParamName: PAnsiChar;
Status: Byte; Type_, MaxLen, DataLen: DBINT; Value: Pointer): RETCODE;
begin
if Assigned(FdbRpcParam)
then Result := FdbRpcParam(dbProc, ParamName, Status, Type_, MaxLen, DataLen, Value)
else Result := FdbRpcParam_stdcall(dbProc, ParamName, Status, Type_, MaxLen, DataLen, Value);
end;
{** Signal the end of a remote procedure call. *}
function TZDBLIBPLainDriver.dbRpcSend(dbProc: PDBPROCESS): RETCODE;
begin
if Assigned(FdbRpcSend)
then Result := FdbRpcSend(dbProc)
else Result := FdbRpcSend_stdcall(dbProc)
end;
{$ENDIF MSWINDOWS}
{** Set the application name in the LOGINREC structure *}
function TZDBLIBPLainDriver.dbSetLApp(Login: PLOGINREC;
AppName: PAnsiChar): RETCODE;
var Item: DBINT;
begin
case FDBLibraryVendorType of
lvtFreeTDS: Item := TDSDBSETAPP;
lvtSybase: Item := SYBDBSETAPP;
else Item := MSDBSETAPP;
end;
Result := dbsetLName(login, AppName, Item)
end;
{** Set the character set in the LOGINREC structure. *}
function TZDBLIBPLainDriver.dbSetLCharSet(Login: PLOGINREC;
CharsetName: PAnsiChar): RETCODE;
begin
case FDBLibraryVendorType of
lvtFreeTDS: Result := dbsetLName(login, CharsetName, TDSDBSETCHARSET);
lvtSybase: Result := dbsetLName(login, CharsetName, SYBDBSETCHARSET);
else Result := DBFAIL;
end;
end;
{** Set the host name in the LOGINREC structure *}
function TZDBLIBPLainDriver.dbSetLHost(Login: PLOGINREC;
HostName: PAnsiChar): RETCODE;
begin
Result := dbsetLName(login, HostName, DBSETHOST)
end;
{$IFDEF MSWINDOWS}
{** Set a value in the LOGINREC structure. *}
function TZDBLIBPLainDriver.dbsetLName(Login: PLOGINREC; Value: PAnsiChar;
Item: Integer): RETCODE;
begin
if Assigned(FdbsetLName)
then Result := FdbsetLName(login, Value, Item)
else Result := FdbsetLName_stdcall(login, Value, Item);
end;
{$ENDIF MSWINDOWS}
(** Set the national language name in the LOGINREC structure. *)
function TZDBLIBPLainDriver.dbSetLNatLang(Login: PLOGINREC;
NatLangName: PAnsiChar): RETCODE;
var Item: DBINT;
begin
case FDBLibraryVendorType of
lvtFreeTDS: Item := TDSDBSETLANG;
lvtSybase: Item := SYBDBSETLANG;
else Item := MSDBSETLANG;
end;
Result := dbsetLName(login, NatLangName, Item)
end;
{$IFDEF MSWINDOWS}
{** Set the number of seconds that DB-Library waits for a server response to
a request for a DBPROCESS connection. *}
function TZDBLIBPLainDriver.dbSetLoginTime(Seconds: Integer): RETCODE;
begin
if Assigned(FdbSetLoginTime)
then Result := FdbSetLoginTime(Seconds)
else Result := FdbSetLoginTime_stdcall(Seconds);
end;
{$ENDIF MSWINDOWS}
{** Set the TDS packet size in an application's LOGINREC structure. *}
function TZDBLIBPLainDriver.dbSetLPacket(Login: PLOGINREC;
packet_size: Word): RETCODE;
begin
case FDBLibraryVendorType of
lvtFreeTDS: Result := dbsetLName(login, @packet_size, TDSDBSETPACKET);
lvtSybase: Result := dbsetLName(login, @packet_size, SYBDBSETPACKET);
else Result := {$IFDEF MSWINDOWS}Fdbsetlpacket{$ELSE}dbsetlpacket{$ENDIF}(Login, packet_size)
end;
end;
{** Set the user server password in the LOGINREC structure. *}
function TZDBLIBPLainDriver.dbSetLPwd(Login: PLOGINREC;
Password: PAnsiChar): RETCODE;
begin
Result := dbsetLName(login, Password, DBSETPWD);
end;
{** Set the TDS packet size in an application's LOGINREC structure. *}
function TZDBLIBPLainDriver.dbSetLSecure(Login: PLOGINREC): RETCODE;
begin
if FDBLibraryVendorType = lvtMS
then Result := dbsetLName(login, nil, MSDBSETSECURE)
else Result := DBFail;
end;
{** Set the user name in the LOGINREC structure. *}
function TZDBLIBPLainDriver.dbSetLUser(Login: PLOGINREC;
UserName: PAnsiChar): RETCODE;
begin
Result := dbsetLName(login, UserName, DBSETUSER);
end;
{$IFDEF MSWINDOWS}
{** Set the maximum number of simultaneously open DBPROCESS structures. *}
function TZDBLIBPLainDriver.dbSetMaxprocs(MaxProcs: SmallInt): RETCODE;
begin
if Assigned(FdbSetMaxprocs_s)
then Result := FdbSetMaxprocs_s(MaxProcs)
else if Assigned(FdbSetMaxprocs_i)
then Result := FdbSetMaxprocs_i(MaxProcs)
else Result := FdbSetMaxprocs_stdcall(MaxProcs);
end;
{** Set a server or DB-Library option. *}
function TZDBLIBPLainDriver.dbSetOpt(dbProc: PDBPROCESS; Option: Integer;
Char_Param: PAnsiChar; Int_Param: Integer): RETCODE;
begin
case FDBLibraryVendorType of
lvtFreeTDS: Result := FdbSetOpt_SYB(dbProc, Option, Char_Param, Int_Param);
lvtSybase: Result := FdbSetOpt_stdcall(dbProc, Option, Char_Param, Int_Param);
else Result := FdbSetOpt_MS(dbProc, Option, Char_Param);
end;
end;
function TZDBLIBPLainDriver.dbSetTime(Seconds: Integer): RETCODE;
begin
if Assigned(FdbSetTime)
then Result := FdbSetTime(Seconds)
else Result := FdbSetTime_stdcall(Seconds);
end;
{$ENDIF MSWINDOWS}
function TZDBLIBPLainDriver.dbsetversion(Version: DBINT): RETCODE;
begin
if Assigned(Fdbsetversion)
then Result := Fdbsetversion(Version)
else {$IFDEF MSWINDOWS}if Assigned(Fdbsetversion_stdcall)
then Result := Fdbsetversion_stdcall(Version)
else {$ENDIF}Result := DBFAIL;
end;
{$IFDEF MSWINDOWS}
{** Send a command batch to the server. *}
function TZDBLIBPLainDriver.dbSqlExec(dbProc: PDBPROCESS): RETCODE;
begin
if Assigned(FdbSqlExec)
then Result := FdbSqlExec(dbProc)
else Result := FdbSqlExec_stdcall(dbProc);
end;
{** Wait for results from the server and verify the correctness of the
instructions the server is responding to. *}
function TZDBLIBPLainDriver.dbSqlOk(dbProc: PDBPROCESS): RETCODE;
begin
if Assigned(FdbSqlOk)
then Result := FdbSqlOk(dbProc)
else Result := FdbSqlOk_stdcall(dbProc);
end;
{** Send a command batch to the server and do not wait for a response. *}
function TZDBLIBPLainDriver.dbsqlsend(dbProc: PDBPROCESS): RETCODE;
begin
if Assigned(Fdbsqlsend)
then Result := Fdbsqlsend(dbProc)
else Result := Fdbsqlsend_stdcall(dbProc);
end;
{** Use a particular database. }
function TZDBLIBPLainDriver.dbUse(dbProc: PDBPROCESS;
dbName: PAnsiChar): RETCODE;
begin
if Assigned(FdbUse)
then Result := FdbUse(dbProc, dbName)
else Result := FdbUse_stdcall(dbProc, dbName);
end;
{** Determine whether the specified regular result column's data can vary in length. *}
function TZDBLIBPLainDriver.dbVaryLen(dbProc: PDBPROCESS;
Column: Integer): DBBOOL;
begin
if Assigned(FdbVaryLen_MS)
then Result := Ord(FdbVaryLen_MS(dbProc, Column))
else if Assigned(Fdbvarylen_SYB)
then Result := Fdbvarylen_SYB(dbProc, Column)
else Result := Fdbvarylen_stdcall(dbProc, Column);
end;
{** Returns the DBLIB version in use *}
function TZDBLIBPLainDriver.dbVersion: PAnsiChar;
begin
if Assigned(Fdbversion) then
Result := Fdbversion
else if Assigned(Fdbversion_stdcall) Then
Result := Fdbversion_stdcall
Else
Result := '';
end;
{$ENDIF MSWINDOWS}
destructor TZDBLIBPLainDriver.Destroy;
begin
if Loader.Loaded then
case FDBLibraryVendorType of
{$IFDEF MSWINDOWS}
lvtMS: begin
dberrhandle(OldMsSQLErrorHandle);
dbmsghandle(OldMsSQLMessageHandle);
//fdbWinexit;
fdbExit;
end;
{$ENDIF}
lvtSybase: begin
{$IFDEF MSWINDOWS}
dberrhandle_stdcall(OldSybaseErrorHandle);
dbmsghandle_stdcall(OldSybaseMessageHandle);
fdbExit_stdcall;
{$ELSE}
dberrhandle(OldSybaseErrorHandle);
dbmsghandle(OldSybaseMessageHandle);
{$IFDEF MSWINDOWS}fdbExit{$ELSE}dbExit{$ENDIF};
{$ENDIF}
end;
else begin //FreeTDS
dberrhandle(OldFreeTDSErrorHandle);
dbmsghandle(OldFreeTDSMessageHandle);
{$IFDEF MSWINDOWS}fdbExit{$ELSE}dbExit{$ENDIF};
end;
end;
inherited Destroy;
end;
{$IFDEF TEST_CALLBACK}
procedure TZDBLIBPLainDriver.DeRegisterErrorHandler(
const Handler: TDbLibErrorHandler);
var MyIdx, OldIdx: Integer;
begin
FCS.Enter;
try
MyIdx := FSQLErrorHandlerList.IndexOf(Handler);
Assert(MyIdx <> -1, 'worng DeRegisterErrorHandler behavior');
if (FSQLErrorHandlerList.Count = 1) then //assign given handle back
{$IFDEF MSWINDOWS}
if Assigned(dberrhandle_stdcall)
then dberrhandle_stdcall(TDbLibErrorHandler(FSQLErrorHandlerList[MyIdx]).FOlddberrhandle_stdcall)
else {$ENDIF} dberrhandle(TDbLibErrorHandler(FSQLErrorHandlerList[MyIdx]).FOlddberrhandle_cdecl)
else begin
if MyIdx = 0
then OldIdx := MyIdx+1
else OldIdx := MyIdx-1;
{$IFDEF MSWINDOWS}
if Assigned(dberrhandle_stdcall)
then TDbLibErrorHandler(FSQLErrorHandlerList[OldIdx]).FOlddberrhandle_stdcall := dberrhandle_stdcall(TDbLibErrorHandler(FSQLErrorHandlerList[MyIdx]).FOlddberrhandle_stdcall)
else {$ENDIF} TDbLibErrorHandler(FSQLErrorHandlerList[OldIdx]).FOlddberrhandle_cdecl := dberrhandle(TDbLibErrorHandler(FSQLErrorHandlerList[MyIdx]).FOlddberrhandle_cdecl);
end;
FSQLErrorHandlerList.Delete(MyIdx);
finally
FCS.Leave;
end;
end;
procedure TZDBLIBPLainDriver.DeRegisterMessageHandler(
const Handler: TDbLibMessageHandler);
var MyIdx, OldIdx: Integer;
begin
FCS.Enter;
try
MyIdx := FSQLMessageHandlerList.IndexOf(Handler);
Assert(MyIdx <> -1, 'worng DeRegisterMessageHandler behavior');
if (FSQLMessageHandlerList.Count = 1) then
{$IFDEF MSWINDOWS}
if Assigned(dbmsghandle_stdcall)
then dbmsghandle_stdcall(TDbLibMessageHandler(FSQLMessageHandlerList[MyIdx]).FOlddbmsghandle_stdcall)
else {$ENDIF} dbmsghandle(TDbLibMessageHandler(FSQLMessageHandlerList[MyIdx]).FOlddbmsghandle_cdecl)
else begin
if MyIdx = 0
then OldIdx := MyIdx+1
else OldIdx := MyIdx-1;
{$IFDEF MSWINDOWS}TDbLibMessageHandler(FSQLMessageHandlerList[OldIdx]).FOlddbMSGhandle_stdcall := TDbLibMessageHandler(FSQLMessageHandlerList[MyIdx]).FOlddbMSGhandle_stdcall;{$ENDIF MSWINDOWS}
TDbLibMessageHandler(FSQLMessageHandlerList[OldIdx]).FOlddbMSGhandle_cdecl := TDbLibMessageHandler(FSQLMessageHandlerList[MyIdx]).FOlddbMSGhandle_cdecl;
end;
FSQLMessageHandlerList.Delete(MyIdx);
finally
FCS.Leave;
end;
end;
{$ENDIF TEST_CALLBACK}
function TZDBLIBPLainDriver.GetDBOption(AOption: TdbOption): DBINT;
begin
case FDBLibraryVendorType of
lvtMS: case AOption of
dboptPARSEONLY: Result := DBLIBDBPARSEONLY;
dboptSHOWPLAN: Result := DBLIBDBSHOWPLAN;
dboptNOEXEC: Result := DBLIBDBNOEXEC;
dboptARITHIGNORE: Result := DBLIBDBARITHIGNORE;
dboptNOCOUNT: Result := DBLIBDBNOCOUNT;
dboptARITHABORT: Result := DBLIBDBARITHABORT;
dboptTEXTLIMIT: Result := DBLIBDBTEXTLIMIT;
dboptOFFSET: Result := DBLIBDBOFFSET;
dboptSTAT: Result := DBLIBDBSTAT;
dboptSTORPROCID: Result := DBLIBDBSTORPROCID;
dboptBUFFER: Result := DBLIBDBBUFFER;
dboptNOAUTOFREE: Result := DBLIBDBNOAUTOFREE;
dboptROWCOUNT: Result := DBLIBDBROWCOUNT;
dboptTEXTSIZE: Result := DBLIBDBTEXTSIZE;
dboptCLIENTCURSORS: Result := DBLIBDBCLIENTCURSORS;
dboptSETTIME: Result := DBLIBDBSET_TIME;
dboptQUOTEDIDENT: Result := DBLIBDBQUOTEDIDENT;
dboptANSITOOEM: Result := DBLIBDBANSITOOEM;
dboptOEMTOANSI: Result := DBLIBDBOEMTOANSI;
else Result := DBNOERR;
end;
else case AOption of
dboptPARSEONLY: Result := TDSPARSEONLY;
dboptESTIMATE: Result := TDSESTIMATE;
dboptSHOWPLAN: Result := TDSSHOWPLAN;
dboptNOEXEC: Result := TDSNOEXEC;
dboptARITHIGNORE: Result := TDSARITHIGNORE;
dboptNOCOUNT: Result := TDSNOCOUNT;
dboptARITHABORT: Result := TDSARITHABORT;
dboptTEXTLIMIT: Result := TDSTEXTLIMIT;
dboptBROWSE: Result := TDSBROWSE;
dboptOFFSET: Result := TDSOFFSET;
dboptSTAT: Result := TDSSTAT;
dboptERRLVL: Result := TDSERRLVL;
dboptCONFIRM: Result := TDSCONFIRM;
dboptSTORPROCID: Result := TDSSTORPROCID;
dboptBUFFER: Result := TDSBUFFER;
dboptNOAUTOFREE: Result := TDSNOAUTOFREE;
dboptROWCOUNT: Result := TDSROWCOUNT;
dboptTEXTSIZE: Result := TDSTEXTSIZE;
dboptNATLANG: Result := TDSNATLANG;
dboptDATEFORMAT: Result := TDSDATEFORMAT;
dboptPRPAD: Result := TDSPRPAD;
dboptPRCOLSEP: Result := TDSPRCOLSEP;
dboptPRLINELEN: Result := TDSPRLINELEN;
dboptPRLINESEP: Result := TDSPRLINESEP;
dboptLFCONVERT: Result := TDSLFCONVERT;
dboptDATEFIRST: Result := TDSDATEFIRST;
dboptCHAINXACTS: Result := TDSCHAINXACTS;
dboptFIPSFLAG: Result := TDSFIPSFLAG;
dboptISOLATION: Result := TDSISOLATION;
dboptAUTH: Result := TDSAUTH;
dboptIDENTITY: Result := TDSIDENTITY;
dboptNOIDCOL: Result := TDSNOIDCOL;
dboptDATESHORT: Result := TDSDATESHORT;
dboptCLIENTCURSORS: Result := TDSCLIENTCURSORS;
dboptSETTIME: Result := TDSSETTIME;
dboptQUOTEDIDENT: Result := TDSQUOTEDIDENT;
else Result := DBNOERR;
end;
end;
end;
procedure TZDBLIBPLainDriver.LoadApi;
begin
with FLoader do begin
//test for not exported methods to identify the libs:
if (GetAddress('dbcolbrowse') <> nil) and //not&never exported by FreeTDS see: http://www.freetds.org/userguide/dblib.api.summary.htm
(GetAddress('dbcoltypeinfo') <> nil) //not exported by ntwdblib.dll
//so we link against a sybaselib with stdcall on windows and cdecl for all other Os's
then FDBLibraryVendorType := lvtSybase
else if (GetAddress('dbcoltypeinfo') <> nil) //ntwdblib.dll does not export that function
then FDBLibraryVendorType := lvtFreeTDS
else FDBLibraryVendorType := lvtMS;
// if type sizes or names are different:
case FDBLibraryVendorType of
lvtFreeTDS: begin
@{$IFDEF MSWINDOWS}Fdbdead{$ELSE}dbdead{$ENDIF} := GetAddress('dbdead', True);
@{$IFDEF MSWINDOWS}Fdbcmdrow{$ELSE}dbcmdrow{$ENDIF} := GetAddress('dbcmdrow');
@{$IFDEF MSWINDOWS}Fdbcount{$ELSE}dbcount{$ENDIF} := GetAddress('dbcount');
@{$IFDEF MSWINDOWS}Fdbcurrow{$ELSE}dbcurrow{$ENDIF} := GetAddress('dbcurrow');
@{$IFDEF MSWINDOWS}Fdbfirstrow{$ELSE}dbfirstrow{$ENDIF} := GetAddress('dbfirstrow');
@{$IFDEF MSWINDOWS}Fdbclose_SYB{$ELSE}dbclose{$ENDIF} := GetAddress('dbclose'); //is a procedure
@{$IFDEF MSWINDOWS}Fdbsetmaxprocs_I{$ELSE}dbSetMaxprocs{$ENDIF} := GetAddress('dbsetmaxprocs'); //uses DBINT
@{$IFDEF MSWINDOWS}Fdbloginfree{$ELSE}dbloginfree{$ENDIF} := GetAddress('dbloginfree', True); //name diff to ms
//@{$IFDEF MSWINDOWS}Fdbcolbrowse_SYB{$ELSE}dbcolbrowse{$ENDIF} := GetAddress('dbcolbrowse'); //no FreeTDS
@{$IFDEF MSWINDOWS}FdbMoreCmds{$ELSE}dbMoreCmds{$ENDIF} := GetAddress('dbmorecmds'); //name diff to ms
@{$IFDEF MSWINDOWS}FdbSetOpt_SYB{$ELSE}dbsetopt{$ENDIF} := GetAddress('dbsetopt'); //int_param is available but not computed always
@{$IFDEF MSWINDOWS}FdbHasRetStat_SYB{$ELSE}dbHasRetStat{$ENDIF} := GetAddress('dbhasretstat'); //DBBOOL vs. LongBool
@{$IFDEF MSWINDOWS}Fdbvarylen_SYB{$ELSE}dbvarylen{$ENDIF} := GetAddress('dbvarylen'); //DBBOOL vs. LongBool
@Fdbinit := GetAddress('dbinit'); //Result is a RetCode
@FdbSetVersion := GetAddress('dbsetversion'); //no MS but ms supports dbSetLVersion
@dbsetlversion := GetAddress('dbsetlversion'); //no sybase see: https://lists.ibiblio.org/pipermail/freetds/2011q4/027489.html
@tdsdump_on := GetAddress('tdsdump_on');
@tdsdump_off := GetAddress('tdsdump_off');
@tdsdump_open := GetAddress('tdsdump_open');
@tdsdump_close := GetAddress('tdsdump_close');
end;
lvtSybase: begin //handle lower vs uppercase and the call conventions
@{$IFDEF MSWINDOWS}Fdbdead_stdcall{$ELSE}dbdead{$ENDIF} := GetAddress('DBDEAD'); //as documented: uppercase
if not Assigned({$IFDEF MSWINDOWS}Fdbdead_stdcall{$ELSE}dbdead{$ENDIF}) then
@{$IFDEF MSWINDOWS}Fdbdead_stdcall{$ELSE}dbdead{$ENDIF} := GetAddress('dbdead'); //lowercase since 15+
@{$IFDEF MSWINDOWS}Fdbcmdrow_stdcall{$ELSE}dbcmdrow{$ENDIF} := GetAddress('DBCMDROW'); //as documented: uppercase
if not Assigned({$IFDEF MSWINDOWS}Fdbcmdrow_stdcall{$ELSE}dbcmdrow{$ENDIF}) then
@{$IFDEF MSWINDOWS}Fdbcmdrow_stdcall{$ELSE}dbcmdrow{$ENDIF} := GetAddress('dbcmdrow'); //lowercase since 15+
@{$IFDEF MSWINDOWS}Fdbcount_stdcall{$ELSE}dbcount{$ENDIF} := GetAddress('DBCOUNT'); //as documented: uppercase
if not Assigned({$IFDEF MSWINDOWS}Fdbcount_stdcall{$ELSE}dbcount{$ENDIF}) then
@{$IFDEF MSWINDOWS}Fdbcount_stdcall{$ELSE}dbcount{$ENDIF} := GetAddress('dbcount'); //lowercase since 15+
@{$IFDEF MSWINDOWS}Fdbcurrow_stdcall{$ELSE}dbcurrow{$ENDIF} := GetAddress('DBCURROW'); //as documented: uppercase
if not Assigned({$IFDEF MSWINDOWS}Fdbcurrow_stdcall{$ELSE}dbcurrow{$ENDIF}) then
@{$IFDEF MSWINDOWS}Fdbcurrow_stdcall{$ELSE}dbcurrow{$ENDIF} := GetAddress('dbcurrow'); //lowercase since 15+
@{$IFDEF MSWINDOWS}Fdbfirstrow_stdcall{$ELSE}dbfirstrow{$ENDIF} := GetAddress('DBFIRSTROW'); //as documented: uppercase
if not Assigned({$IFDEF MSWINDOWS}Fdbfirstrow_stdcall{$ELSE}dbfirstrow{$ENDIF}) then
@{$IFDEF MSWINDOWS}Fdbfirstrow_stdcall{$ELSE}dbfirstrow{$ENDIF} := GetAddress('dbfirstrow'); //lowercase since 15+
@{$IFDEF MSWINDOWS}Fdbclose_stdcall{$ELSE}dbclose{$ENDIF} := GetAddress('dbclose');
@{$IFDEF MSWINDOWS}Fdbsetmaxprocs_stdcall{$ELSE}dbSetMaxprocs{$ENDIF} := GetAddress('dbsetmaxprocs');
@{$IFDEF MSWINDOWS}Fdbloginfree_stdcall{$ELSE}dbloginfree{$ENDIF} := GetAddress('dbloginfree', True); //name diff
@{$IFDEF MSWINDOWS}Fdbcolbrowse_stdcall{$ELSE}dbcolbrowse{$ENDIF} := GetAddress('dbcolbrowse'); //no FreeTDS
@{$IFDEF MSWINDOWS}FdbMoreCmds_stdcall{$ELSE}dbMoreCmds{$ENDIF} := GetAddress('DBMORECMDS'); //uppercase
if not Assigned({$IFDEF MSWINDOWS}FdbMoreCmds_stdcall{$ELSE}dbMoreCmds{$ENDIF}) then
@{$IFDEF MSWINDOWS}FdbMoreCmds_stdcall{$ELSE}dbMoreCmds{$ENDIF} := GetAddress('dbmorecmds'); //lowercase since 15+
@{$IFDEF MSWINDOWS}FdbSetOpt_stdcall{$ELSE}dbsetopt{$ENDIF} := GetAddress('dbsetopt'); //int_param is available
@{$IFDEF MSWINDOWS}FdbHasRetStat_stdcall{$ELSE}dbhasretstat{$ENDIF} := GetAddress('dbhasretstat'); //DBBOOL vs. LongBool
@{$IFDEF MSWINDOWS}Fdbvarylen_stdcall{$ELSE}dbvarylen{$ENDIF} := GetAddress('dbvarylen'); //DBBOOL vs. LongBool
@{$IFDEF MSWINDOWS}Fdbinit_stdcall{$ELSE}Fdbinit{$ENDIF} := GetAddress('dbinit'); //Result is a RetCode
@{$IFDEF MSWINDOWS}FdbSetVersion_stdcall{$ELSE}FdbSetVersion{$ENDIF} := GetAddress('dbsetversion'); //no MS
end;
{$IFDEF MSWINDOWS}
lvtMS: begin
@FdbWinexit := GetAddress('dbwinexit');
@Fdbdead_MS := GetAddress('dbdead', True);
@Fdbcmdrow := GetAddress('dbcmdrow');
@Fdbcount := GetAddress('dbcount');
@Fdbcurrow := GetAddress('dbcurrow');
@Fdbfirstrow := GetAddress('dbfirstrow');
@Fdbclose_MS := GetAddress('dbclose'); //is a function
@Fdbsetlpacket := GetAddress('dbsetlpacket'); //does not use the dbsetlname method
@Fdbsetmaxprocs_s := GetAddress('dbsetmaxprocs'); //uses a two byte int
@Fdbloginfree := GetAddress('dbfreelogin', True);//name diff
@Fdbcolbrowse_MS := GetAddress('dbcolbrowse'); //no FreeTDS
@FdbMoreCmds := GetAddress('dbmorecmds'); //name diff to ms
@FdbSetOpt_MS := GetAddress('dbsetopt'); //int_param is not available
@FdbHasRetStat_MS := GetAddress('dbhasretstat'); //DBBOOL vs. LongBool
@Fdbvarylen_MS := GetAddress('dbvarylen'); //DBBOOL vs. LongBool
@Fdbinit_MS := GetAddress('dbinit'); //Result is a PAnsiChar not a RetCode
@dbsetlversion := GetAddress('dbsetlversion') //no sybase see: https://lists.ibiblio.org/pipermail/freetds/2011q4/027489.html
end;
{$ENDIF}
end;
{ type sizes are equal -> call convention! }
{$IFDEF MSWINDOWS}
if FDBLibraryVendorType = lvtSybase then begin
@Fdbadata_stdcall := GetAddress('dbadata');
@Fdbadlen_stdcall := GetAddress('dbadlen');
@Fdbaltbind_stdcall := GetAddress('dbaltbind');
@Fdbaltbind_ps_stdcall := GetAddress('dbaltbind_ps');
@Fdbaltcolid_stdcall := GetAddress('dbaltcolid');
@Fdbaltlen_stdcall := GetAddress('dbaltlen');
@Fdbaltop_stdcall := GetAddress('dbaltop');
@Fdbalttype_stdcall := GetAddress('dbalttype');
@Fdbanullbind_stdcall := GetAddress('dbanullbind');
@Fdbbind_stdcall := GetAddress('dbbind');
@Fdbbind_ps_stdcall := GetAddress('dbbind_ps');
@Fdbbufsize_stdcall := GetAddress('dbbufsize');
@Fdbbylist_stdcall := GetAddress('dbbylist');
@Fdbcancel_stdcall := GetAddress('dbcancel');
@Fdbcanquery_stdcall := GetAddress('dbcanquery');
@Fdbclrbuf_stdcall := GetAddress('dbclrbuf');
@Fdbcmd_stdcall := GetAddress('dbcmd');
@Fdbclropt_stdcall := GetAddress('dbclropt');
@Fdbcollen_stdcall := GetAddress('dbcollen');
@Fdbcolname_stdcall := GetAddress('dbcolname');
@Fdbcolsource_stdcall := GetAddress('dbcolsource');
@Fdbcoltype_stdcall := GetAddress('dbcoltype');
@Fdbcolutype_stdcall := GetAddress('dbcolutype');
@Fdbcoltypeinfo_stdcall := GetAddress('dbcoltypeinfo'); //no MS ?
@Fdbcolutype_stdcall := GetAddress('dbcolutype');
@Fdbconvert_stdcall := GetAddress('dbconvert');
@Fdbconvert_ps_stdcall := GetAddress('bconvert_ps'); //no MS
@Fdbdata_stdcall := GetAddress('dbdata');
@Fdbdatlen_stdcall := GetAddress('dbdatlen');
@Fdbexit_stdcall := GetAddress('dbexit');
@Fdbfreebuf_stdcall := GetAddress('dbfreebuf');
@Fdbfreequal_stdcall := GetAddress('dbfreequal');
@Fdbgetchar_stdcall := GetAddress('dbgetchar');
@Fdbgetcharset_stdcall := GetAddress('dbgetcharset');
@FdbGetRow_stdcall := GetAddress('dbgetrow');
@FdbLogin_stdcall := GetAddress('dblogin');
@Fdbname_stdcall := GetAddress('dbname');
@FdbNextRow_stdcall := GetAddress('dbnextrow');
@FdbNumCols_stdcall := GetAddress('dbnumcols');
@FdbOpen_stdcall := GetAddress('dbopen');
@FdbSetLoginTime_stdcall := GetAddress('dbsetlogintime');
@FdbsetLName_stdcall := GetAddress('dbsetlname');
@FdbSetTime_stdCall := GetAddress('dbsettime');
@FdbSqlExec_stdcall := GetAddress('dbsqlexec');
@FdbSqlOk_stdcall := GetAddress('dbsqlok');
@FdbSqlSend_stdcall := GetAddress('dbsqlsend');
@FdbResults_stdcall := GetAddress('dbresults');
@FdbRetData_stdcall := GetAddress('dbretdata');
@FdbRetLen_stdcall := GetAddress('dbretlen');
@FdbRetName_stdcall := GetAddress('dbretname');
@Fdbretstatus_stdcall := GetAddress('dbretstatus');
@FdbRetType_stdcall := GetAddress('dbrettype');
@Fdbrpcinit_stdcall := GetAddress('dbrpcinit');
@FdbRpcParam_stdcall := GetAddress('dbrpcparam');
@FdbRpcSend_stdcall := GetAddress('dbrpcsend');
@Fdbuse_stdcall := GetAddress('dbuse');
@dberrhandle_stdcall := GetAddress('dberrhandle');
@dbmsghandle_stdcall := GetAddress('dbmsghandle');
{$IFNDEF TEST_CALLBACK}
OldSybaseErrorHandle := dberrhandle_stdcall(SybaseErrorHandle);
OldSybaseMessageHandle := dbmsghandle_stdcall(SybaseMessageHandle);
{$ENDIF}
end else {$ENDIF}begin
@{$IFDEF MSWINDOWS}Fdbadata{$ELSE}dbadata{$ENDIF} := GetAddress('dbadata');
@{$IFDEF MSWINDOWS}Fdbadlen{$ELSE}dbadlen{$ENDIF} := GetAddress('dbadlen');
@{$IFDEF MSWINDOWS}Fdbaltbind{$ELSE}dbaltbind{$ENDIF} := GetAddress('dbaltbind');
@{$IFDEF MSWINDOWS}Fdbaltbind_ps{$ELSE}dbaltbind_ps{$ENDIF} := GetAddress('dbaltbind_ps');
@{$IFDEF MSWINDOWS}Fdbaltcolid{$ELSE}dbaltcolid{$ENDIF} := GetAddress('dbaltcolid');
@{$IFDEF MSWINDOWS}Fdbaltlen{$ELSE}dbaltlen{$ENDIF} := GetAddress('dbaltlen');
@{$IFDEF MSWINDOWS}Fdbaltop{$ELSE}dbaltop{$ENDIF} := GetAddress('dbaltop');
@{$IFDEF MSWINDOWS}Fdbalttype{$ELSE}dbalttype{$ENDIF} := GetAddress('dbalttype');
@{$IFDEF MSWINDOWS}Fdbanullbind{$ELSE}dbanullbind{$ENDIF} := GetAddress('dbanullbind');
@{$IFDEF MSWINDOWS}Fdbbind{$ELSE}dbbind{$ENDIF} := GetAddress('dbbind');
@{$IFDEF MSWINDOWS}Fdbbind_ps{$ELSE}dbbind_ps{$ENDIF} := GetAddress('dbbind_ps');
@{$IFDEF MSWINDOWS}Fdbbufsize{$ELSE}dbbufsize{$ENDIF} := GetAddress('dbbufsize');
@{$IFDEF MSWINDOWS}Fdbbylist{$ELSE}dbbylist{$ENDIF} := GetAddress('dbbylist');
@{$IFDEF MSWINDOWS}Fdbcancel{$ELSE}dbcancel{$ENDIF} := GetAddress('dbcancel');
@{$IFDEF MSWINDOWS}Fdbcanquery{$ELSE}dbcanquery{$ENDIF} := GetAddress('dbcanquery');
@{$IFDEF MSWINDOWS}Fdbclrbuf{$ELSE}dbclrbuf{$ENDIF} := GetAddress('dbclrbuf');
@{$IFDEF MSWINDOWS}Fdbclropt{$ELSE}dbclropt{$ENDIF} := GetAddress('dbclropt');
@{$IFDEF MSWINDOWS}Fdbcmd{$ELSE}dbcmd{$ENDIF} := GetAddress('dbcmd');
@{$IFDEF MSWINDOWS}Fdbcollen{$ELSE}dbcollen{$ENDIF} := GetAddress('dbcollen');
@dbcolinfo := GetAddress('dbcolinfo'); //no sybase but freeTDS and MS
@dbtablecolinfo := GetAddress('dbtablecolinfo'); //FreeTDS only!!!
@{$IFDEF MSWINDOWS}Fdbcolname{$ELSE}dbcolname{$ENDIF} := GetAddress('dbcolname');
@{$IFDEF MSWINDOWS}Fdbcolsource{$ELSE}dbcolsource{$ENDIF} := GetAddress('dbcolsource'); //no FreeTDS?
@{$IFDEF MSWINDOWS}Fdbcoltype{$ELSE}dbcoltype{$ENDIF} := GetAddress('dbcoltype');
@{$IFDEF MSWINDOWS}Fdbcoltypeinfo{$ELSE}dbcoltypeinfo{$ENDIF} := GetAddress('dbcoltypeinfo'); //no MS
@{$IFDEF MSWINDOWS}Fdbcolutype{$ELSE}dbcolutype{$ENDIF} := GetAddress('dbcolutype');
@{$IFDEF MSWINDOWS}Fdbconvert{$ELSE}dbconvert{$ENDIF} := GetAddress('dbconvert');
@{$IFDEF MSWINDOWS}Fdbconvert_ps{$ELSE}dbconvert_ps{$ENDIF} := GetAddress('bconvert_ps'); //no MS
@{$IFDEF MSWINDOWS}Fdbdata{$ELSE}dbdata{$ENDIF} := GetAddress('dbdata');
{$IFDEF MSWINDOWS}@dbdataready := GetAddress('dbdata'); {$ENDIF}
@{$IFDEF MSWINDOWS}Fdbdatlen{$ELSE}dbdatlen{$ENDIF} := GetAddress('dbdatlen');
@{$IFDEF MSWINDOWS}Fdbexit{$ELSE}dbexit{$ENDIF} := GetAddress('dbexit');
@{$IFDEF MSWINDOWS}Fdbfreebuf{$ELSE}dbfreebuf{$ENDIF} := GetAddress('dbfreebuf');
@{$IFDEF MSWINDOWS}Fdbfreequal{$ELSE}dbfreequal{$ENDIF} := GetAddress('dbfreequal');
@{$IFDEF MSWINDOWS}Fdbgetchar{$ELSE}dbgetchar{$ENDIF} := GetAddress('dbgetchar');
@{$IFDEF MSWINDOWS}Fdbgetcharset{$ELSE}dbgetcharset{$ENDIF} := GetAddress('dbgetcharset');
@{$IFDEF MSWINDOWS}FdbGetRow{$ELSE}dbGetRow{$ENDIF} := GetAddress('dbgetrow');
@FdbLogin := GetAddress('dblogin');
@{$IFDEF MSWINDOWS}Fdbname{$ELSE}dbname{$ENDIF} := GetAddress('dbname');
@{$IFDEF MSWINDOWS}FdbNextRow{$ELSE}dbNextRow{$ENDIF} := GetAddress('dbnextrow');
@{$IFDEF MSWINDOWS}FdbNumCols{$ELSE}dbnumcols{$ENDIF} := GetAddress('dbnumcols');
@{$IFDEF MSWINDOWS}FdbResults{$ELSE}dbResults{$ENDIF} := GetAddress('dbresults');
@Fdbopen := GetAddress('dbopen');
@FtdsDbOpen := GetAddress('tdsdbopen');
@{$IFDEF MSWINDOWS}Fdbretdata{$ELSE}dbretdata{$ENDIF} := GetAddress('dbretdata');
@{$IFDEF MSWINDOWS}Fdbretlen{$ELSE}dbretlen{$ENDIF} := GetAddress('dbretlen');
@{$IFDEF MSWINDOWS}Fdbretname{$ELSE}dbretname{$ENDIF} := GetAddress('dbretname');
@{$IFDEF MSWINDOWS}Fdbretstatus{$ELSE}dbretstatus{$ENDIF} := GetAddress('dbretstatus');
@{$IFDEF MSWINDOWS}Fdbrettype{$ELSE}dbrettype{$ENDIF} := GetAddress('dbrettype');
@{$IFDEF MSWINDOWS}Fdbrpcinit{$ELSE}dbrpcinit{$ENDIF} := GetAddress('dbrpcinit');
@{$IFDEF MSWINDOWS}Fdbrpcparam{$ELSE}dbrpcparam{$ENDIF} := GetAddress('dbrpcparam');
@{$IFDEF MSWINDOWS}FdbRpcSend{$ELSE}dbRpcSend{$ENDIF} := GetAddress('dbrpcsend');
@{$IFDEF MSWINDOWS}FdbSetLoginTime{$ELSE}dbSetLoginTime{$ENDIF} := GetAddress('dbsetlogintime');
@{$IFDEF MSWINDOWS}FdbsetLName{$ELSE}dbsetLName{$ENDIF} := GetAddress('dbsetlname');
@{$IFDEF MSWINDOWS}FdbSetTime{$ELSE}dbSetTime{$ENDIF} := GetAddress('dbsettime');
@{$IFDEF MSWINDOWS}FdbSqlExec{$ELSE}dbSqlExec{$ENDIF} := GetAddress('dbsqlexec');
@{$IFDEF MSWINDOWS}FdbSqlOk{$ELSE}dbSqlOk{$ENDIF} := GetAddress('dbsqlok');
@{$IFDEF MSWINDOWS}FdbSqlSend{$ELSE}dbSqlSend{$ENDIF} := GetAddress('dbsqlsend');
@{$IFDEF MSWINDOWS}Fdbuse{$ELSE}dbuse{$ENDIF} := GetAddress('dbuse');
@{$IFDEF MSWINDOWS}Fdbversion{$ELSE}dbversion{$ENDIF} := GetAddress('dbversion');
@dbmsghandle := GetAddress('dbmsghandle');
@dberrhandle := GetAddress('dberrhandle');
if FDBLibraryVendorType = lvtFreeTDS then begin
OldFreeTDSErrorHandle := dberrhandle(FreeTDSErrorHandle);
OldFreeTDSMessageHandle := dbmsghandle(FreeTDSMessageHandle);
end else begin
{$IFDEF MSWINDOWS}OldMsSQLErrorHandle{$ELSE}OldSybaseErrorHandle{$ENDIF} := dberrhandle(DbLibErrorHandle);
{$IFDEF MSWINDOWS}OldMsSQLMessageHandle{$ELSE}OldSybaseMessageHandle{$ENDIF} := dbmsghandle(DbLibMessageHandle);
end;
Assert(dbintit = SUCCEED, 'dbinit failed');
end;
end;
end;
procedure TZDBLIBPLainDriver.LoadCodePages;
begin
//inherited;
{ add FreeTDS supported charactersets }
AddCodePage('UTF-8', 1, ceUTF8, zCP_UTF8, '', 4, True);
AddCodePage('ISO-8859-1', 2, ceAnsi, zCP_L1_ISO_8859_1, '', 1, True);
AddCodePage('ASCII', 3, ceAnsi, zCP_us_ascii, '', 1, False);
end;
{$IFDEF TEST_CALLBACK}
function TZDBLIBPLainDriver.GetErrorHandler(dbProc: PDBPROCESS;
ADBERRHANDLE_PROC: TDBERRHANDLE_PROC): IZDBLibErrorHandler;
var DbLibErrorHandler: TDbLibErrorHandler;
begin
FCS.Enter;
Result := nil;
try
DbLibErrorHandler := TDbLibErrorHandler.Create(dbProc, ADBERRHANDLE_PROC, Self);
Result := DbLibErrorHandler;
FSQLErrorHandlerList.Add(DbLibErrorHandler);
finally
FCS.Leave;
end;
end;
function TZDBLIBPLainDriver.GetMessageHandler(dbProc: PDBPROCESS;
ADBMSGHANDLE_PROC: TDBMSGHANDLE_PROC): IZDBLibMessageHandler;
var DbLibMessageHandler: TDbLibMessageHandler;
begin
FCS.Enter;
Result := nil;
try
DbLibMessageHandler := TDbLibMessageHandler.Create(dbProc, ADBMSGHANDLE_PROC, Self);
Result := DbLibMessageHandler;
FSQLMessageHandlerList.Add(DbLibMessageHandler);
finally
FCS.Leave;
end;
end;
constructor TZMethodToDllCallbackProcedure.Create(const Instance: TObject;
methodAddr: pointer; const CallBackManager: TZDBLIBPLainDriver);
begin
inherited Create(Instance, methodAddr);
FManager := CallBackManager;
end;
{ TDbLibErrorHandler }
procedure TDbLibErrorHandler.BeforeDestruction;
begin
inherited;
FManager.DeRegisterErrorHandler(Self);
end;
constructor TDbLibErrorHandler.Create(Handle: PDBPROCESS;
DBERRHANDLE_PROC: TDBERRHANDLE_PROC; const Manager: TZDBLIBPLainDriver);
var P: Pointer;
begin
P := GetProcedureAddress;
{$IFDEF MSWINDOWS}
if Manager.FDBLibraryVendorType = lvtSybase then begin
inherited Create(Self, @TDbLibErrorHandler.dberrhandle_stdcall, Manager);
FOlddberrhandle_stdcall := Manager.dberrhandle_stdcall(P);
end else {$ENDIF}begin
inherited Create(Self, @TDbLibErrorHandler.dberrhandle_cdecl, Manager);
FOlddberrhandle_cdecl := Manager.dberrhandle(P);
end;
FHandle := Handle;
FMydberrhandle := DBERRHANDLE_PROC;
end;
function TDbLibErrorHandler.dberrhandle_cdecl(Proc: PDBPROCESS;
Severity, DbErr, OsErr: Integer; DbErrStr, OsErrStr: PAnsiChar): Integer;
begin
if FHandle = Proc
then Result := FMydberrhandle(Proc, Severity, DbErr, OsErr, DbErrStr, OsErrStr)
else if Assigned(FOlddberrhandle_cdecl)
then Result := FOlddberrhandle_cdecl(Proc, Severity, DbErr, OsErr, DbErrStr, OsErrStr)
else Result := INT_CANCEL;
end;
{$IFDEF MSWINDOWS}
function TDbLibErrorHandler.dberrhandle_stdcall(Proc: PDBPROCESS;
Severity, DbErr, OsErr: Integer; DbErrStr, OsErrStr: PAnsiChar): Integer;
begin
if FHandle = Proc
then Result := FMydberrhandle(Proc, Severity, DbErr, OsErr, DbErrStr, OsErrStr)
else if Assigned(FOlddberrhandle_stdcall)
then Result := FOlddberrhandle_stdcall(Proc, Severity, DbErr, OsErr, DbErrStr, OsErrStr)
else Result := INT_CANCEL;
end;
{$ENDIF MSWINDOWS}
{ TDbLibMessageHandler }
procedure TDbLibMessageHandler.BeforeDestruction;
begin
inherited;
FManager.DeRegisterMessageHandler(Self);
end;
constructor TDbLibMessageHandler.Create(
Handle: PDBPROCESS; DBMSGHANDLE_PROC: TDBMSGHANDLE_PROC;
const Manager: TZDBLIBPLainDriver);
var P: Pointer;
begin
P := GetProcedureAddress;
{$IFDEF MSWINDOWS}
if Manager.FDBLibraryVendorType = lvtSybase then begin
inherited Create(Self, @TDbLibMessageHandler.dbmsghandle_stdcall, Manager);
FOlddbmsghandle_stdcall := Manager.dbmsghandle_stdcall(P);
end else {$ENDIF}begin
inherited Create(Self, PAnsiChar(@TDbLibMessageHandler.dbmsghandle_cdecl), Manager);
FOlddbmsghandle_cdecl := Manager.dbmsghandle(P);
end;
FMydbmsghandle := DBMSGHANDLE_PROC;
FHandle := Handle;
end;
function TDbLibMessageHandler.dbmsghandle_cdecl(Proc: PDBPROCESS; MsgNo: DBINT;
MsgState, Severity: Integer; MsgText, SrvName, ProcName: PAnsiChar;
Line: DBUSMALLINT): Integer;
begin
if FHandle = Proc
then Result := FMydbmsghandle(Proc, MsgNo, MsgState, Severity, MsgText, SrvName, ProcName, Line)
else if Assigned(FOlddbmsghandle_cdecl)
then Result := FOlddbmsghandle_cdecl(Proc, MsgNo, MsgState, Severity, MsgText, SrvName, ProcName, Line)
else Result := INT_EXIT;
end;
{$IFDEF MSWINDOWS}
function TDbLibMessageHandler.dbmsghandle_stdcall(Proc: PDBPROCESS;
MsgNo: DBINT; MsgState, Severity: Integer; MsgText, SrvName,
ProcName: PAnsiChar; Line: DBUSMALLINT): Integer;
begin
if FHandle = Proc
then Result := FMydbmsghandle(Proc, MsgNo, MsgState, Severity, MsgText, SrvName, ProcName, Line)
else if Assigned(FOlddbmsghandle_stdcall)
then Result := FOlddbmsghandle_stdcall(Proc, MsgNo, MsgState, Severity, MsgText, SrvName, ProcName, Line)
else Result := INT_EXIT;
end;
{$ENDIF}
{$ENDIF TEST_CALLBACK}
{ TMSSQLDBLibPLainDriver }
procedure TMSSQLDBLibPLainDriver.AfterConstruction;
begin
inherited;
{$IFDEF MSWINDOWS}
FLoader.AddLocation('ntwdblib.dll');
{$ENDIF}
end;
function TMSSQLDBLibPLainDriver.Clone: IZPlainDriver;
begin
Result := TMSSQLDBLibPLainDriver.Create;
end;
function TMSSQLDBLibPLainDriver.GetDescription: string;
begin
Result := 'Native dblib driver for SQL Server';
end;
function TMSSQLDBLibPLainDriver.GetProtocol: string;
begin
Result := 'mssql'
end;
procedure TMSSQLDBLibPLainDriver.LoadCodePages;
begin
inherited LoadCodePages;
AddmMSCodePages(Self);
end;
{ TSybaseDBLibPLainDriver }
procedure TSybaseDBLibPLainDriver.AfterConstruction;
begin
inherited AfterConstruction;
FLoader.AddLocation('libsybdb'+SharedSuffix);
end;
function TSybaseDBLibPLainDriver.Clone: IZPlainDriver;
begin
Result := TSybaseDBLibPLainDriver.Create;
end;
function TSybaseDBLibPLainDriver.GetDescription: string;
begin
Result := 'Native dblib driver for Sybase ASE';
end;
function TSybaseDBLibPLainDriver.GetProtocol: string;
begin
Result := 'sybase'
end;
procedure TSybaseDBLibPLainDriver.LoadApi;
var
Success: Boolean;
begin
inherited LoadApi;
{$IFDEF MSWINDOWS}
if assigned(FdbSetVersion) then begin
if FdbSetVersion(TDSDBVERSION_100) = DBFAIL then begin
Success := FdbSetVersion(TDSDBVERSION_46) = DBSUCCEED;
Assert(Success , 'failed to set the TDS version')
end;
end else begin
if FdbSetVersion_stdcall(TDSDBVERSION_100) = DBFAIL then begin
Success := FdbSetVersion_stdcall(TDSDBVERSION_46) = DBSUCCEED;
Assert(Success , 'failed to set the TDS version');
end;
end;
{$ELSE}
if dbSetVersion(TDSDBVERSION_100) = DBFAIL then begin
Success := dbSetVersion(TDSDBVERSION_46) = DBSUCCEED;
Assert(Success , 'failed to set the TDS version')
end;
{$ENDIF}
end;
procedure TSybaseDBLibPLainDriver.LoadCodePages;
begin
inherited;
AddSybaseCodePages(Self);
end;
{ TZDBLibErrorList }
constructor TZDBLibErrorList.Create;
begin
inherited Create(SizeOf(TDBLibError), True);
end;
procedure TZDBLibErrorList.Notify(Ptr: Pointer; Action: TListNotification);
begin
if Action = lnDeleted then begin
PDBLibError(Ptr).DbErrStr := EmptyRaw;
PDBLibError(Ptr).OsErrStr := EmptyRaw;
end;
end;
{ TZDBLibMessageList }
constructor TZDBLibMessageList.Create;
begin
inherited Create(SizeOf(TDBLibMessage), True);
end;
procedure TZDBLibMessageList.Notify(Ptr: Pointer; Action: TListNotification);
begin
if Action = lnDeleted then begin
PDBLibMessage(Ptr).MsgText := EmptyRaw;
PDBLibMessage(Ptr).SrvName := EmptyRaw;
PDBLibMessage(Ptr).ProcName := EmptyRaw;
end;
end;
{ Helper functions for TDS_DATETIMEALL}
function TdsDateTimeAllGetPrecision(const Value: TDBDATETIMEALL): Integer;
begin
Result := Value.flags and DbDateTimeAllTimePrecMask;
end;
function TdsDateTimeAllHasDate(const Value: TDBDATETIMEALL): Boolean;
begin
Result := WordBool(Value.flags and DbDateTimeAllHasDateMask)
end;
function TdsDateTimeAllHasTime(const Value: TDBDATETIMEALL): Boolean;
begin
Result := WordBool(Value.flags and DbDateTimeAllHasTimeMask)
end;
function TdsDateTimeAllHasOffset(const Value: TDBDATETIMEALL): Boolean;
begin
Result := WordBool(Value.flags and DbDatetimeAllHasOffsetMask)
end;
initialization
SQLErrors := TZDBLibErrorList.Create;
SQLMessages := TZDBLibMessageList.Create;
ErrorCS := TCriticalSection.Create;
finalization
FreeAndnil(ErrorCS);
//Free any record in the list if any
FreeAndNil(SQLErrors);
//Free any record in the list if any
FreeAndNil(SQLMessages);
{$ENDIF ZEOS_DISABLE_DBLIB}
end.