dblib.pp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699
  1. {
  2. This file is part of the Free Component Library (FCL)
  3. Copyright (c) 2010 by the Free Pascal development team
  4. Header files Microsoft DB-Library for C: sqlfront.h, sqldb.h
  5. and FreeTDS: sybdb.h
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. The Original Code was created by (c) 2010 Ladislav Karrach (Windows)
  12. for the Free Pascal project.
  13. **********************************************************************
  14. FreeTDS (http://www.freetds.org/userguide/choosingtdsprotocol.htm):
  15. tds version = 5.0 - Sybase System 10 and above
  16. 7.0 - MS SQL Server 7
  17. 7.1 - MS SQL Server 2000 (*default*)
  18. 7.2 - MS SQL Server 2005
  19. 7.3 - MS SQL Server 2008
  20. 7.4 - MS SQL Server 2012/2014
  21. tds version can be set using env.var. TDSVER or in freetds.conf or .freetds.conf
  22. }
  23. unit DBLib;
  24. {$IFDEF FPC}{$mode objfpc}{$ENDIF}{$H+}
  25. { $DEFINE ntwdblib} //if you are using MS SQL Server Client Library (ntwdblib.dll)
  26. {$IFNDEF ntwdblib}
  27. {$DEFINE freetds} //if you are using db-lib from FreeTDS project (MS SQL Server + Sybase support)
  28. {$ENDIF}
  29. {$DEFINE LOAD_DYNAMICALLY}
  30. interface
  31. const
  32. DBLIBDLL=
  33. {$IFDEF WINDOWS}
  34. {$IFDEF ntwdblib}'ntwdblib.dll'{$ENDIF}
  35. {$IFDEF freetds} 'dblib.dll' {$ENDIF}
  36. {$ELSE}
  37. {$IFDEF DARWIN}
  38. 'libsybdb.dylib'
  39. {$ELSE}
  40. 'libsybdb.so'
  41. {$ENDIF}
  42. {$ENDIF}
  43. ;
  44. //from sybdb.h:
  45. //DBVERSION_xxx are used with dbsetlversion()
  46. DBVERSION_100= 2; // Sybase TDS 5.0
  47. DBVERSION_42 = 3; // This can be used for old Microsoft and Sybase servers
  48. DBVERSION_70 = 4;
  49. DBVERSION_71 = 5;
  50. DBVERSION_72 = 6;
  51. DBVERSION_73 = 7;
  52. DBVERSION_74 = 8;
  53. //DBTDS_xxx are returned by DBTDS()
  54. DBTDS_UNKNOWN= 0;
  55. DBTDS_42 = 4; // SQL Server 4.2
  56. DBTDS_50 = 7; // Sybase SQL Server 5.0; use this for connecting to Sybase (ASA or ASE)
  57. DBTDS_70 = 8; // Microsoft SQL Server 7.0
  58. DBTDS_71 = 9; // Microsoft SQL Server 2000
  59. DBTDS_72 = 10; // Microsoft SQL Server 2005
  60. DBTDS_73 = 11; // Microsoft SQL Server 2008
  61. DBTDS_74 = 12; // Microsoft SQL Server 2012/2014
  62. //from sqlfront.h , sybdb.h for FreeTDS
  63. DBSETHOST=1;
  64. DBSETUSER=2;
  65. DBSETPWD =3;
  66. DBSETAPP ={$IFDEF freetds}5{$ELSE}4{$ENDIF};
  67. {$IFDEF freetds}
  68. DBSETHID = 4;
  69. DBSETBCP = 6;
  70. DBSETNATLANG= 7;
  71. DBSETNOSHORT= 8;
  72. DBSETHIER = 9;
  73. DBSETCHARSET= 10;
  74. DBSETPACKET = 11;
  75. DBSETENCRYPT= 12;
  76. DBSETLABELED= 13;
  77. DBSETDBNAME = 14;
  78. {$ELSE}
  79. DBSETID = 5;
  80. DBSETLANG = 6;
  81. DBSETSECURE = 7;
  82. DBSET_LOGINTIME=10;
  83. DBSETFALLBACK=12;
  84. {$ENDIF}
  85. //These two are defined by Microsoft for dbsetlversion():
  86. DBVER42={$IFDEF freetds}DBVERSION_42{$ELSE}8{$ENDIF};
  87. DBVER60={$IFDEF freetds}DBVERSION_71{$ELSE}9{$ENDIF};
  88. //dboptions:
  89. DBNOAUTOFREE = {$IFDEF freetds}15{$ELSE}8{$ENDIF};
  90. DBTEXTLIMIT = {$IFDEF freetds}7{$ELSE}4{$ENDIF};
  91. DBTEXTSIZE = {$IFDEF freetds}17{$ELSE}5{$ENDIF};
  92. DBANSItoOEM = 14;
  93. DBOEMtoANSI = 15;
  94. DBQUOTEDIDENT= {$IFDEF freetds}35{$ELSE}18{$ENDIF};
  95. // settings from here are purely FreeTDS extensions:
  96. DBSETUTF16 = 1001;
  97. DBSETNTLMV2 = 1002;
  98. DBSETREADONLY= 1003;
  99. TIMEOUT_IGNORE=-1;
  100. TIMEOUT_INFINITE=0;
  101. SUCCEED=1;
  102. FAIL=0;
  103. NO_MORE_RESULTS=2;
  104. NO_MORE_RPC_RESULTS=3;
  105. MORE_ROWS=-1;
  106. REG_ROW=MORE_ROWS;
  107. NO_MORE_ROWS=-2;
  108. BUF_FULL=-3; //only if buffering is turned on
  109. INT_EXIT=0;
  110. INT_CONTINUE=1;
  111. INT_CANCEL=2;
  112. SQLVOID=$1f;
  113. SQLTEXT=$23;
  114. SQLVARBINARY=$25;
  115. SQLINTN=$26; //all nullable integers
  116. SQLVARCHAR=$27;
  117. SQLBINARY=$2d;
  118. SQLIMAGE=$22;
  119. SQLCHAR=$2f;
  120. SQLINT1=$30;
  121. SQLBIT=$32;
  122. SQLINT2=$34;
  123. SQLINT4=$38;
  124. SQLMONEY=$3c;
  125. SQLDATETIME=$3d;
  126. SQLFLT8=$3e;
  127. SQLFLTN=$6d;
  128. SQLMONEYN=$6e;
  129. SQLDATETIMN=$6f;
  130. SQLFLT4=$3b;
  131. SQLMONEY4=$7a;
  132. SQLDATETIM4=$3a;
  133. SQLDECIMAL=$6a;
  134. SQLNUMERIC=$6c;
  135. // from proto.h:
  136. SYBNTEXT=$63;
  137. // MS only types:
  138. SYBINT8 =$7F;
  139. SYBUNIQUE =$24;
  140. SYBVARIANT=$62;
  141. SYBMSUDT =$F0;
  142. SYBMSXML =$F1;
  143. SYBMSDATE =$28;
  144. SYBMSTIME =$29;
  145. SYBMSDATETIME2=$2A;
  146. SYBMSDATETIMEOFFSET=$2B;
  147. MAXTABLENAME ={$IFDEF freetds}512+1{$ELSE}30{$ENDIF};
  148. MAXCOLNAMELEN={$IFDEF freetds}512+1{$ELSE}30{$ENDIF};
  149. MAXNUMERICLEN={$IFDEF freetds}32 {$ELSE}16{$ENDIF};
  150. DBMAXCHAR=256; // Max length of DBVARBINARY and DBVARCHAR, etc.
  151. DEFAULTPRECISION = 18;
  152. DEFAULTSCALE = 0;
  153. // Used by dbcolinfo:
  154. CI_REGULAR=1;
  155. CI_ALTERNATE=2;
  156. CI_CURSOR=3;
  157. DBUNKNOWN = 2; //FALSE = 0, TRUE = 1
  158. // Error codes:
  159. SYBEFCON = 20002; // SQL Server connection failed
  160. SYBEWRIT = 20006; // Write to SQL Server failed.
  161. SYBESMSG = 20018; // General SQL Server error: Check messages from the SQL Server.
  162. SYBEDDNE = 20047; // DBPROCESS is dead or not enabled.
  163. type
  164. PLOGINREC=Pointer;
  165. PDBPROCESS=Pointer;
  166. RETCODE=integer;
  167. STATUS=integer;
  168. INT=longint;
  169. SHORT=smallint;
  170. BOOL=longbool;
  171. ULONG=longword;
  172. // DB-Library datatypes
  173. DBBOOL=byte; // unsigned char
  174. DBCHAR=shortint;
  175. DBBIT=byte;
  176. DBTINYINT=byte;
  177. DBSMALLINT=smallint; // 16-bit int (short)
  178. DBUSMALLINT=word; // 16-bit unsigned int (unsigned short)
  179. DBINT=longint; // 32-bit int (int)
  180. DBUINT=longword; // 32-bit unsigned int
  181. DBBIGINT=int64; // 64-bit integer
  182. DBUBIGINT=qword; // 64-bit unsigned
  183. DBFLT8=double; // 64-bit real (double)
  184. DBBINARY=byte;
  185. {$PACKRECORDS C}
  186. DBDATETIME=packed record
  187. dtdays: DBINT;
  188. dttime: ULONG;
  189. end;
  190. PDBDATETIME=^DBDATETIME;
  191. DBDATETIMEALL=record
  192. time: DBUBIGINT; // time, 7 digit precision (64-bit unsigned)
  193. date: DBINT; // date, 0 = 1900-01-01 (32-bit int)
  194. offset: DBSMALLINT; // time offset (16-bit int)
  195. info: word; // unsigned short time_prec:3;
  196. // unsigned short _res:10;
  197. // unsigned short has_time:1;
  198. // unsigned short has_date:1;
  199. // unsigned short has_offset:1;
  200. end;
  201. PDBDATETIMEALL=^DBDATETIMEALL;
  202. // DBDATEREC structure used by dbdatecrack
  203. DBDATEREC=packed record
  204. case boolean of
  205. false:(
  206. oldyear:INT; // 1753 - 9999
  207. oldmonth: INT; // 1 - 12
  208. oldday: INT; // 1 - 31
  209. olddayofyear: INT; // 1 - 366 (in sybdb.h dayofyear and day are changed around!)
  210. oldweekday: INT; // 1 - 7 (Mon - Sun)
  211. oldhour: INT; // 0 - 23
  212. oldminute: INT; // 0 - 59
  213. oldsecond: INT; // 0 - 59
  214. oldmillisecond: INT; // 0 - 999
  215. oldtzone: INT; // 0 - 127 (Sybase only!)
  216. );
  217. true:(
  218. year:INT; // 1753 - 9999
  219. quarter:INT; // 1 - 4
  220. month: INT; // 1 - 12
  221. {$IFDEF freetds}
  222. day: INT; // 1 - 31
  223. dayofyear: INT; // 1 - 366 (in sybdb.h dayofyear and day are changed around!)
  224. {$ELSE}
  225. dayofyear: INT; // 1 - 366 (in sybdb.h dayofyear and day are changed around!)
  226. day: INT; // 1 - 31
  227. {$ENDIF}
  228. week: INT; // 1 - 54 (for leap years)
  229. weekday: INT; // 1 - 7 (Mon - Sun)
  230. hour: INT; // 0 - 23
  231. minute: INT; // 0 - 59
  232. second: INT; // 0 - 59
  233. millisecond: INT; // 0 - 999
  234. tzone: INT; // -840 - 840
  235. );
  236. end;
  237. PDBDATEREC=^DBDATEREC;
  238. DBDATEREC2 = record
  239. year: DBINT; // 1753 - 9999
  240. quarter: DBINT; // 1 - 4
  241. month: DBINT; // 1 - 12
  242. day: DBINT; // 1 - 31
  243. dayofyear: DBINT; // 1 - 366
  244. week: DBINT; // 1 - 54 (for leap years)
  245. weekday: DBINT; // 1 - 7 (Mon. - Sun.)
  246. hour: DBINT; // 0 - 23
  247. minute: DBINT; // 0 - 59
  248. second: DBINT; // 0 - 59
  249. nanosecond: DBINT; // 0 - 999999999
  250. tzone: DBINT; // 0 - 127 (Sybase only)
  251. end;
  252. PDBDATEREC2=^DBDATEREC2;
  253. DBMONEY=record
  254. mnyhigh: DBINT;
  255. mnylow: ULONG;
  256. end;
  257. DBNUMERIC=packed record
  258. precision: BYTE;
  259. scale: BYTE;
  260. sign: BYTE; // 1 = Positive, 0 = Negative
  261. val: array[0..MAXNUMERICLEN-1] of BYTE;
  262. end;
  263. DBVARYBIN=packed record
  264. len: {$IFDEF freetds}DBINT{$ELSE}DBSMALLINT{$ENDIF};
  265. bytes: array[0..DBMAXCHAR-1] of BYTE;
  266. end;
  267. DBVARYCHAR=packed record
  268. len: {$IFDEF freetds}DBINT{$ELSE}DBSMALLINT{$ENDIF};
  269. str: array[0..DBMAXCHAR-1] of AnsiChar;
  270. end;
  271. DBERRHANDLE_PROC=function(dbproc: PDBPROCESS; severity, dberr, oserr:INT; dberrstr, oserrstr:PAnsiChar):INT; cdecl;
  272. DBMSGHANDLE_PROC=function(dbproc: PDBPROCESS; msgno: DBINT; msgstate, severity:INT; msgtext, srvname, procname:PAnsiChar; line:DBUSMALLINT):INT; cdecl;
  273. {$IFDEF ntwdblib}
  274. {$PACKRECORDS 2}
  275. {$ENDIF}
  276. DBCOL=record
  277. SizeOfStruct: DBINT;
  278. Name: array[0..MAXCOLNAMELEN] of AnsiChar;
  279. ActualName: array[0..MAXCOLNAMELEN] of AnsiChar;
  280. TableName: array[0..MAXTABLENAME] of AnsiChar;
  281. Typ: SHORT;
  282. UserType: DBINT;
  283. MaxLength: DBINT;
  284. Precision: BYTE;
  285. Scale: BYTE;
  286. VarLength: BOOL; // TRUE, FALSE
  287. Null: BYTE; // TRUE, FALSE or DBUNKNOWN
  288. CaseSensitive: BYTE; // TRUE, FALSE or DBUNKNOWN
  289. Updatable: BYTE; // TRUE, FALSE or DBUNKNOWN
  290. Identity: BOOL; // TRUE, FALSE
  291. end;
  292. PDBCOL=^DBCOL;
  293. {$PACKRECORDS DEFAULT}
  294. var
  295. DBLibInit: boolean=false; //was dbinit() already called ?
  296. {$IFNDEF LOAD_DYNAMICALLY}
  297. function dbinit():{$IFDEF freetds}RETCODE{$ELSE}PAnsiChar{$ENDIF}; cdecl; external DBLIBDLL;
  298. function dblogin():PLOGINREC; cdecl; external DBLIBDLL;
  299. function dbsetlname(login:PLOGINREC; value:PAnsiChar; which:INT):RETCODE; cdecl; external DBLIBDLL;
  300. function dbsetlogintime(seconds:INT):RETCODE; cdecl; external DBLIBDLL;
  301. function dbsettime(seconds:INT):RETCODE; cdecl; external DBLIBDLL;
  302. function dberrhandle(handler:DBERRHANDLE_PROC):DBERRHANDLE_PROC; cdecl; external DBLIBDLL;
  303. function dbmsghandle(handler:DBMSGHANDLE_PROC):DBMSGHANDLE_PROC; cdecl; external DBLIBDLL;
  304. function dbsetopt(dbproc:PDBPROCESS; option: INT; param:PAnsiChar {$IFDEF freetds};int_param:INT{$ENDIF}):RETCODE; cdecl; external DBLIBDLL;
  305. function dbuse(dbproc:PDBPROCESS; dbname:PAnsiChar):RETCODE; cdecl; external DBLIBDLL;
  306. function dbcmd(dbproc:PDBPROCESS; cmdstring:PAnsiChar):RETCODE; cdecl; external DBLIBDLL;
  307. function dbcmdrow(dbproc:PDBPROCESS):RETCODE; cdecl; external DBLIBDLL;
  308. function dbsqlexec(dbproc:PDBPROCESS):RETCODE; cdecl; external DBLIBDLL;
  309. function dbresults(dbproc:PDBPROCESS):RETCODE; cdecl; external DBLIBDLL;
  310. function dbmorecmds(dbproc:PDBPROCESS):RETCODE; cdecl; external DBLIBDLL;
  311. function dbnextrow(dbproc:PDBPROCESS):STATUS; cdecl; external DBLIBDLL;
  312. function dbnumcols(dbproc:PDBPROCESS):INT; cdecl; external DBLIBDLL;
  313. function dbcolname(dbproc:PDBPROCESS; column:INT):PAnsiChar; cdecl; external DBLIBDLL;
  314. function dbcoltype(dbproc:PDBPROCESS; column:INT):INT; cdecl; external DBLIBDLL;
  315. function dbcollen(dbproc:PDBPROCESS; column:INT):DBINT; cdecl; external DBLIBDLL;
  316. function dbcolinfo(dbproc:PDBPROCESS; typ:INT; column:DBINT; computeid:DBINT; dbcol:PDBCOL):RETCODE; cdecl; external DBLIBDLL;
  317. function dbprtype(token:INT):PAnsiChar; cdecl; external DBLIBDLL;
  318. function dbdatlen(dbproc:PDBPROCESS; column:INT):DBINT; cdecl; external DBLIBDLL;
  319. function dbdata(dbproc:PDBPROCESS; column:INT):PByte; cdecl; external DBLIBDLL;
  320. function dbwillconvert(srctype, desttype: INT):{$IFDEF freetds}DBBOOL{$ELSE}BOOL{$ENDIF}; cdecl; external DBLIBDLL;
  321. function dbconvert(dbproc:PDBPROCESS; srctype:INT; src:PByte; srclen:DBINT; desttype:INT; dest:PByte; destlen:DBINT):INT; cdecl; external DBLIBDLL;
  322. function dbdatecrack(dbproc:PDBPROCESS; dateinfo:PDBDATEREC; datetime: PDBDATETIME):RETCODE; cdecl; external DBLIBDLL;
  323. function dbcount(dbproc:PDBPROCESS):DBINT; cdecl; external DBLIBDLL;
  324. function dbiscount(dbproc:PDBPROCESS):BOOL; cdecl; external DBLIBDLL;
  325. function dbcancel(dbproc:PDBPROCESS):RETCODE; cdecl; external DBLIBDLL;
  326. function dbcanquery(dbproc:PDBPROCESS):RETCODE; cdecl; external DBLIBDLL;
  327. function dbdead(dbproc:PDBPROCESS):DBBOOL; cdecl; external DBLIBDLL;
  328. function dbhasretstat(dbproc:PDBPROCESS):DBBOOL; cdecl; external DBLIBDLL;
  329. function dbretstatus(dbproc:PDBPROCESS):DBINT; cdecl; external DBLIBDLL;
  330. procedure dbfreelogin(login:PLOGINREC); cdecl; external DBLIBDLL {$IFDEF freetds}name 'dbloginfree'{$ENDIF};
  331. procedure dbexit(); cdecl; external DBLIBDLL;
  332. {$IFDEF ntwdblib}
  333. function dbopen(login:PLOGINREC; servername:PAnsiChar):PDBPROCESS; cdecl; external DBLIBDLL;
  334. function dbclose(dbproc:PDBPROCESS):RETCODE; cdecl; external DBLIBDLL;
  335. procedure dbwinexit; cdecl; external DBLIBDLL;
  336. {$ENDIF}
  337. {$IFDEF freetds}
  338. function tdsdbopen(login:PLOGINREC; servername:PAnsiChar; msdblib:INT):PDBPROCESS; cdecl; external DBLIBDLL;
  339. function dbtablecolinfo(dbproc:PDBPROCESS; column:DBINT; dbcol:PDBCOL):RETCODE; cdecl; external DBLIBDLL;
  340. function dbtds(dbproc:PDBPROCESS):INT; cdecl; external DBLIBDLL;
  341. function dbsetlversion(login:PLOGINREC; version:BYTE):RETCODE; cdecl; external DBLIBDLL;
  342. function dbservcharset(dbproc:PDBPROCESS):PAnsiChar; cdecl; external DBLIBDLL;
  343. procedure dbclose(dbproc:PDBPROCESS); cdecl; external DBLIBDLL;
  344. {$ENDIF}
  345. {$ELSE}
  346. var
  347. dbinit: function():{$IFDEF freetds}RETCODE{$ELSE}PAnsiChar{$ENDIF}; cdecl;
  348. dblogin: function():PLOGINREC; cdecl;
  349. dbsetlname: function(login:PLOGINREC; value:PAnsiChar; which:INT):RETCODE; cdecl;
  350. dbsetlogintime: function(seconds:INT):RETCODE; cdecl;
  351. dbsettime: function(seconds:INT):RETCODE; cdecl;
  352. dberrhandle: function(handler:DBERRHANDLE_PROC):DBERRHANDLE_PROC; cdecl;
  353. dbmsghandle: function(handler:DBMSGHANDLE_PROC):DBMSGHANDLE_PROC; cdecl;
  354. dbsetopt: function(dbproc:PDBPROCESS; option: INT; param:PAnsiChar {$IFDEF freetds};int_param:INT{$ENDIF}):RETCODE; cdecl;
  355. dbuse: function(dbproc:PDBPROCESS; dbname:PAnsiChar):RETCODE; cdecl;
  356. dbcmd: function(dbproc:PDBPROCESS; cmdstring:PAnsiChar):RETCODE; cdecl;
  357. dbcmdrow: function(dbproc:PDBPROCESS):RETCODE; cdecl;
  358. dbsqlexec: function(dbproc:PDBPROCESS):RETCODE; cdecl;
  359. dbresults: function(dbproc:PDBPROCESS):RETCODE; cdecl;
  360. dbmorecmds: function(dbproc:PDBPROCESS):RETCODE; cdecl;
  361. dbnextrow: function(dbproc:PDBPROCESS):STATUS; cdecl;
  362. dbnumcols: function(dbproc:PDBPROCESS):INT; cdecl;
  363. dbcolname: function(dbproc:PDBPROCESS; column:INT):PAnsiChar; cdecl;
  364. dbcoltype: function(dbproc:PDBPROCESS; column:INT):INT; cdecl;
  365. dbcollen: function(dbproc:PDBPROCESS; column:INT):DBINT; cdecl;
  366. dbcolinfo: function(dbproc:PDBPROCESS; typ:INT; column:DBINT; computeid:DBINT; dbcol:PDBCOL):RETCODE; cdecl;
  367. dbprtype: function(token:INT):PAnsiChar; cdecl;
  368. dbdatlen: function(dbproc:PDBPROCESS; column:INT):DBINT; cdecl;
  369. dbdata: function(dbproc:PDBPROCESS; column:INT):PByte; cdecl;
  370. dbwillconvert: function(srctype, desttype: INT):{$IFDEF freetds}DBBOOL{$ELSE}BOOL{$ENDIF}; cdecl;
  371. dbconvert: function(dbproc:PDBPROCESS; srctype:INT; src:PByte; srclen:DBINT; desttype:INT; dest:PByte; destlen:DBINT):INT; cdecl;
  372. dbdatecrack: function(dbproc:PDBPROCESS; dateinfo:PDBDATEREC; datetime: PDBDATETIME):RETCODE; cdecl;
  373. dbcount: function(dbproc:PDBPROCESS):DBINT; cdecl;
  374. dbiscount: function(dbproc:PDBPROCESS):BOOL; cdecl;
  375. dbcancel: function(dbproc:PDBPROCESS):RETCODE; cdecl;
  376. dbcanquery: function(dbproc:PDBPROCESS):RETCODE; cdecl;
  377. dbdead: function(dbproc:PDBPROCESS):DBBOOL; cdecl;
  378. dbhasretstat: function(dbproc:PDBPROCESS):DBBOOL; cdecl;
  379. dbretstatus: function(dbproc:PDBPROCESS):DBINT; cdecl;
  380. dbexit: procedure(); cdecl;
  381. dbfreelogin: procedure(login:PLOGINREC); cdecl;
  382. {$IFDEF ntwdblib}
  383. dbopen: function(login:PLOGINREC; servername:PAnsiChar):PDBPROCESS; cdecl;
  384. dbclose: function(dbproc:PDBPROCESS):RETCODE; cdecl;
  385. dbwinexit: procedure; cdecl;
  386. {$ENDIF}
  387. {$IFDEF freetds}
  388. tdsdbopen: function(login:PLOGINREC; servername:PAnsiChar; msdblib:INT):PDBPROCESS; cdecl;
  389. dbanydatecrack: function(dbproc:PDBPROCESS; di: PDBDATEREC2; typ: INT; data: pointer):RETCODE; cdecl;
  390. dbtablecolinfo: function(dbproc:PDBPROCESS; column:DBINT; dbcol:PDBCOL):RETCODE; cdecl;
  391. dbtds: function(dbproc:PDBPROCESS):INT; cdecl;
  392. dbsetlversion: function(login:PLOGINREC; version:BYTE):RETCODE; cdecl;
  393. dbservcharset: function(dbproc:PDBPROCESS):PAnsiChar; cdecl;
  394. dbclose: procedure(dbproc:PDBPROCESS); cdecl;
  395. {$ENDIF}
  396. DefaultDBLibLibraryName: string = DBLIBDLL;
  397. DBLibLoadedLibrary: string = '';
  398. {$ENDIF}
  399. {$IFDEF ntwdblib}
  400. function tdsdbopen(login:PLOGINREC; servername:PAnsiChar; msdblib:INT):PDBPROCESS;
  401. function dbtablecolinfo(dbproc:PDBPROCESS; column:DBINT; dbcol:PDBCOL):RETCODE;
  402. function dbsetlversion(login:PLOGINREC; version:BYTE):RETCODE;
  403. function dbtds(dbproc:PDBPROCESS):INT;
  404. function dbversion():PAnsiChar;
  405. {$ENDIF}
  406. {$IFDEF freetds}
  407. function dbopen(login:PLOGINREC; servername:PAnsiChar):PDBPROCESS;
  408. procedure dbwinexit;
  409. {$ENDIF}
  410. function dbsetlcharset(login:PLOGINREC; charset:PAnsiChar):RETCODE;
  411. function dbsetlsecure(login:PLOGINREC):RETCODE;
  412. function dbdatetimeallcrack(dta: PDBDATETIMEALL): TDateTime;
  413. function dbmoneytocurr(pdbmoney: PQWord): Currency; inline;
  414. function InitialiseDBLib(const LibraryName : ansistring): integer;
  415. procedure ReleaseDBLib;
  416. implementation
  417. {$IFDEF LOAD_DYNAMICALLY}
  418. uses SysUtils, Dynlibs;
  419. var DBLibLibraryHandle: TLibHandle;
  420. RefCount: integer;
  421. function InitialiseDBLib(const LibraryName : ansistring): integer;
  422. var libname : string;
  423. begin
  424. inc(RefCount);
  425. Result:=RefCount;
  426. if RefCount = 1 then
  427. begin
  428. if LibraryName='' then
  429. libname:=DefaultDBLibLibraryName
  430. else
  431. libname:=LibraryName;
  432. DBLibLibraryHandle := LoadLibrary(libname);
  433. if DBLibLibraryHandle = nilhandle then
  434. begin
  435. RefCount := 0;
  436. raise EInOutError.CreateFmt('Can not load DB-Lib client library "%s". Check your installation.'+LineEnding+'%s',
  437. [libname, SysErrorMessage(GetLastOSError)]);
  438. end;
  439. DBLibLoadedLibrary := libname;
  440. pointer(dbinit) := GetProcedureAddress(DBLibLibraryHandle,'dbinit');
  441. pointer(dblogin) := GetProcedureAddress(DBLibLibraryHandle,'dblogin');
  442. pointer(dbsetlname) := GetProcedureAddress(DBLibLibraryHandle,'dbsetlname');
  443. pointer(dbsetlogintime) := GetProcedureAddress(DBLibLibraryHandle,'dbsetlogintime');
  444. pointer(dbsettime) := GetProcedureAddress(DBLibLibraryHandle,'dbsettime');
  445. pointer(dberrhandle) := GetProcedureAddress(DBLibLibraryHandle,'dberrhandle');
  446. pointer(dbmsghandle) := GetProcedureAddress(DBLibLibraryHandle,'dbmsghandle');
  447. pointer(dbsetopt) := GetProcedureAddress(DBLibLibraryHandle,'dbsetopt');
  448. pointer(dbuse) := GetProcedureAddress(DBLibLibraryHandle,'dbuse');
  449. pointer(dbcmd) := GetProcedureAddress(DBLibLibraryHandle,'dbcmd');
  450. pointer(dbcmdrow) := GetProcedureAddress(DBLibLibraryHandle,'dbcmdrow');
  451. pointer(dbsqlexec) := GetProcedureAddress(DBLibLibraryHandle,'dbsqlexec');
  452. pointer(dbresults) := GetProcedureAddress(DBLibLibraryHandle,'dbresults');
  453. pointer(dbmorecmds) := GetProcedureAddress(DBLibLibraryHandle,'dbmorecmds');
  454. pointer(dbnextrow) := GetProcedureAddress(DBLibLibraryHandle,'dbnextrow');
  455. pointer(dbnumcols) := GetProcedureAddress(DBLibLibraryHandle,'dbnumcols');
  456. pointer(dbcolname) := GetProcedureAddress(DBLibLibraryHandle,'dbcolname');
  457. pointer(dbcoltype) := GetProcedureAddress(DBLibLibraryHandle,'dbcoltype');
  458. pointer(dbcollen) := GetProcedureAddress(DBLibLibraryHandle,'dbcollen');
  459. pointer(dbcolinfo) := GetProcedureAddress(DBLibLibraryHandle,'dbcolinfo');
  460. pointer(dbprtype) := GetProcedureAddress(DBLibLibraryHandle,'dbprtype');
  461. pointer(dbdatlen) := GetProcedureAddress(DBLibLibraryHandle,'dbdatlen');
  462. pointer(dbdata) := GetProcedureAddress(DBLibLibraryHandle,'dbdata');
  463. pointer(dbwillconvert) := GetProcedureAddress(DBLibLibraryHandle,'dbwillconvert');
  464. pointer(dbconvert) := GetProcedureAddress(DBLibLibraryHandle,'dbconvert');
  465. pointer(dbdatecrack) := GetProcedureAddress(DBLibLibraryHandle,'dbdatecrack');
  466. pointer(dbcount) := GetProcedureAddress(DBLibLibraryHandle,'dbcount');
  467. pointer(dbiscount) := GetProcedureAddress(DBLibLibraryHandle,'dbiscount');
  468. pointer(dbcancel) := GetProcedureAddress(DBLibLibraryHandle,'dbcancel');
  469. pointer(dbcanquery) := GetProcedureAddress(DBLibLibraryHandle,'dbcanquery');
  470. pointer(dbdead) := GetProcedureAddress(DBLibLibraryHandle,'dbdead');
  471. pointer(dbhasretstat) := GetProcedureAddress(DBLibLibraryHandle,'dbhasretstat');
  472. pointer(dbretstatus) := GetProcedureAddress(DBLibLibraryHandle,'dbretstatus');
  473. pointer(dbexit) := GetProcedureAddress(DBLibLibraryHandle,'dbexit');
  474. pointer(dbfreelogin) := GetProcedureAddress(DBLibLibraryHandle,{$IFDEF freetds}'dbloginfree'{$ELSE}'dbfreelogin'{$ENDIF});
  475. pointer(dbclose) := GetProcedureAddress(DBLibLibraryHandle,'dbclose');
  476. {$IFDEF ntwdblib}
  477. pointer(dbopen) := GetProcedureAddress(DBLibLibraryHandle,'dbopen');
  478. pointer(dbwinexit) := GetProcedureAddress(DBLibLibraryHandle,'dbwinexit');
  479. {$ENDIF}
  480. {$IFDEF freetds}
  481. pointer(tdsdbopen) := GetProcedureAddress(DBLibLibraryHandle,'tdsdbopen');
  482. pointer(dbtablecolinfo) := GetProcedureAddress(DBLibLibraryHandle,'dbtablecolinfo');
  483. pointer(dbtds) := GetProcedureAddress(DBLibLibraryHandle,'dbtds');
  484. pointer(dbsetlversion) := GetProcedureAddress(DBLibLibraryHandle,'dbsetlversion');
  485. pointer(dbservcharset) := GetProcedureAddress(DBLibLibraryHandle,'dbservcharset');
  486. {$ENDIF}
  487. DBLibInit:=false;
  488. end;
  489. end;
  490. procedure ReleaseDBLib;
  491. begin
  492. if RefCount > 0 then dec(RefCount);
  493. if RefCount = 0 then
  494. begin
  495. dbexit;{$IFDEF WINDOWS}dbwinexit;{$ENDIF}
  496. if UnloadLibrary(DBLibLibraryHandle) then
  497. begin
  498. DBLibLibraryHandle := NilHandle;
  499. DBLibLoadedLibrary := '';
  500. end
  501. else
  502. inc(RefCount);
  503. end;
  504. end;
  505. {$ELSE}
  506. procedure InitialiseDBLib(LibraryName : string);
  507. begin
  508. //no-op for static linked
  509. end;
  510. procedure ReleaseDBLib;
  511. begin
  512. //no-op for static linked
  513. end;
  514. {$ENDIF LOAD_DYNAMICALLY}
  515. //functions, which are not implemented by FreeTDS:
  516. {$IFDEF freetds}
  517. function dbopen(login:PLOGINREC; servername:PAnsiChar):PDBPROCESS;
  518. begin
  519. Result:=tdsdbopen(login, servername, 1{1=MSDBLIB or 0=SYBDBLIB});
  520. end;
  521. function dbsetlcharset(login:PLOGINREC; charset:PAnsiChar):RETCODE;
  522. begin
  523. Result:=dbsetlname(login, charset, 10);
  524. end;
  525. function dbsetlsecure(login:PLOGINREC):RETCODE;
  526. begin
  527. //not implemented; see http://www.freetds.org/userguide/domains.htm
  528. Result:=SUCCEED;
  529. end;
  530. procedure dbwinexit;
  531. begin
  532. //do nothing
  533. end;
  534. {$ENDIF}
  535. //functions which are not implemented by ntwdblib:
  536. {$IFDEF ntwdblib}
  537. function tdsdbopen(login:PLOGINREC; servername:PAnsiChar; msdblib:INT):PDBPROCESS;
  538. begin
  539. Result:=dbopen(login, servername);
  540. end;
  541. function dbtablecolinfo(dbproc:PDBPROCESS; column:DBINT; dbcol:PDBCOL):RETCODE;
  542. begin
  543. Result:=dbcolinfo(dbproc, CI_REGULAR, column, 0, dbcol);
  544. if dbcol^.VarLength {true also when column is nullable} then
  545. case dbcol^.Typ of
  546. SQLCHAR : dbcol^.Typ := SQLVARCHAR;
  547. SQLBINARY: dbcol^.Typ := SQLVARBINARY;
  548. end;
  549. end;
  550. function dbsetlversion(login:PLOGINREC; version:BYTE):RETCODE;
  551. begin
  552. Result:=dbsetlname(login, nil, version);
  553. end;
  554. function dbsetlcharset(login:PLOGINREC; charset:PAnsiChar):RETCODE;
  555. begin
  556. Result:=SUCCEED;
  557. end;
  558. function dbsetlsecure(login:PLOGINREC):RETCODE;
  559. begin
  560. Result:=dbsetlname(login, nil, DBSETSECURE);
  561. end;
  562. function dbtds(dbproc:PDBPROCESS):INT;
  563. begin
  564. Result:=0;
  565. end;
  566. function dbversion():PAnsiChar;
  567. begin
  568. Result:='DB Library version 8.00';
  569. end;
  570. {$ENDIF}
  571. function dbdatetimeallcrack(dta: PDBDATETIMEALL): TDateTime;
  572. begin
  573. if dta^.info and $4000 = 0 then
  574. Result := 0
  575. else
  576. Result := dta^.date + 2;
  577. Result := ComposeDateTime(Result, dta^.time/MSecsPerDay/10000 + dta^.offset/MinsPerDay);
  578. end;
  579. function dbmoneytocurr(pdbmoney: PQWord): Currency; inline;
  580. begin
  581. PQWord(@Result)^ := {$IFDEF ENDIAN_LITTLE}Swap(pdbmoney^){$ELSE}pdbmoney^{$ENDIF};
  582. end;
  583. {
  584. //ntwdblib uses low significant values first
  585. //freetds uses variable length array (based on precision) see numeric.c: tds_numeric_bytes_per_prec
  586. // and starts from high significant values first
  587. function dbnumerictobcd(dbnum: DBNUMERIC): TBCD;
  588. var i: integer;
  589. intval,intbase,intdiv: int64;
  590. bcdval,bcdbase,bcddiv, bcd1: TBCD;
  591. begin
  592. intval:=0;
  593. intbase:=1;
  594. for i:=0 to 6 do
  595. begin
  596. intval := intval + dbnum.val[i] * intbase;
  597. intbase:= intbase*256;
  598. end;
  599. bcdval := IntegerToBCD(intval);
  600. if dbnum.precision > 16 then
  601. begin
  602. bcdbase := IntegerToBCD(intbase);
  603. for i:=7 to length(dbnum.val)-1 do
  604. begin
  605. BCDMultiply(bcdbase, integer(dbnum.val[i]), bcd1);
  606. BCDAdd(bcdval, bcd1, bcdval);
  607. BCDMultiply(bcdbase, 256, bcdbase);
  608. end;
  609. end;
  610. if dbnum.scale > 18 then
  611. begin
  612. bcddiv:=IntegerToBCD(int64(1000000000000000000));
  613. for i:=19 to dbnum.scale do BCDMultiply(bcddiv, 10, bcddiv);
  614. end
  615. else
  616. begin
  617. intdiv:=1;
  618. for i:=1 to dbnum.scale do intdiv:=intdiv*10;
  619. bcddiv:=IntegerToBCD(intdiv);
  620. end;
  621. BCDDivide(bcdval, bcddiv, Result);
  622. if dbnum.sign=0 then BCDNegate(Result);
  623. end;
  624. }
  625. {$IFNDEF LOAD_DYNAMICALLY}
  626. finalization
  627. dbexit; {$IFDEF WINDOWS}dbwinexit;{$ENDIF}
  628. {$ENDIF}
  629. end.