1 {*********************************************************}
3 { Zeos Database Objects }
4 { Native Plain Drivers for MySQL }
6 { Originally written by Sergey Seroukhov }
9 { Pascal Data Objects Library }
11 { Copyright (c) 2006 John Marino, www.synsport.com }
13 {*********************************************************}
15 {@********************************************************}
16 { Copyright (c) 1999-2012 Zeos Development Group }
18 { License Agreement: }
20 { This library is distributed in the hope that it will be }
21 { useful, but WITHOUT ANY WARRANTY; without even the }
22 { implied warranty of MERCHANTABILITY or FITNESS FOR }
23 { A PARTICULAR PURPOSE. See the GNU Lesser General }
24 { Public License for more details. }
26 { The source code of the ZEOS Libraries and packages are }
27 { distributed under the Library GNU General Public }
28 { License (see the file COPYING / COPYING.ZEOS) }
29 { with the following modification: }
30 { As a special exception, the copyright holders of this }
31 { library give you permission to link this library with }
32 { independent modules to produce an executable, }
33 { regardless of the license terms of these independent }
34 { modules, and to copy and distribute the resulting }
35 { executable under terms of your choice, provided that }
36 { you also meet, for each linked independent module, }
37 { the terms and conditions of the license of that module. }
38 { An independent module is a module which is not derived }
39 { from or based on this library. If you modify this }
40 { library, you may extend this exception to your version }
41 { of the library, but you are not obligated to do so. }
42 { If you do not wish to do so, delete this exception }
43 { statement from your version. }
46 { The project web site is located on: }
47 { http://zeos.firmos.at (FORUM) }
48 { http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}
49 { svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN) }
51 { http://www.sourceforge.net/projects/zeoslib. }
54 { Zeos Development Group. }
55 {********************************************************@}
57 unit ZPlainMySqlDriver;
63 uses Classes, {$IFDEF MSEgui}mclasses,{$ENDIF}
64 ZPlainDriver, ZCompatibility, ZPlainMySqlConstants, ZTokenizer;
67 MARIADB_LOCATION = 'libmariadb'+ SharedSuffix;
69 {$IFNDEF MYSQL_STRICT_DLL_LOADING}
70 WINDOWS_DLL_LOCATION = 'libmysql.dll';
71 WINDOWS_DLL_LOCATION_EMBEDDED = 'libmysqld.dll';
73 WINDOWS_DLL41_LOCATION = 'libmysql41.dll';
74 WINDOWS_DLL41_LOCATION_EMBEDDED = 'libmysqld41.dll';
75 WINDOWS_DLL50_LOCATION = 'libmysql50.dll';
76 WINDOWS_DLL50_LOCATION_EMBEDDED = 'libmysqld50.dll';
77 WINDOWS_DLL51_LOCATION = 'libmysql51.dll';
78 WINDOWS_DLL51_LOCATION_EMBEDDED = 'libmysqld51.dll';
79 WINDOWS_DLL55_LOCATION = 'libmysql55.dll';
80 WINDOWS_DLL55_LOCATION_EMBEDDED = 'libmysqld55.dll';
82 {$IFNDEF MYSQL_STRICT_DLL_LOADING}
83 LINUX_DLL_LOCATION = 'libmysqlclient'+SharedSuffix;
84 LINUX_DLL_LOCATION_EMBEDDED = 'libmysqld'+SharedSuffix;
86 LINUX_DLL41_LOCATION = 'libmysqlclient'+SharedSuffix+'.14';
87 LINUX_DLL41_LOCATION_EMBEDDED = 'libmysqld'+SharedSuffix+'.14';
88 LINUX_DLL50_LOCATION = 'libmysqlclient'+SharedSuffix+'.15';
89 LINUX_DLL50_LOCATION_EMBEDDED = 'libmysqld'+SharedSuffix+'.15';
90 LINUX_DLL51_LOCATION = 'libmysqlclient'+SharedSuffix+'.16';
91 LINUX_DLL51_LOCATION_EMBEDDED = 'libmysqld'+SharedSuffix+'.16';
92 LINUX_DLL55_LOCATION = 'libmysqlclient'+SharedSuffix+'.18';
93 LINUX_DLL55_LOCATION_EMBEDDED = 'libmysqld'+SharedSuffix+'.18';
97 {** Represents a generic interface to MySQL native API. }
98 IZMySQLPlainDriver = interface (IZPlainDriver)
99 ['{D1CB3F6C-72A1-4125-873F-791202ACC5F0}']
100 function IsMariaDBDriver: Boolean;
101 {ADDED by fduenas 15-06-2006}
102 function GetClientVersion: Integer;
103 function GetServerVersion(Handle: PZMySQLConnect): Integer;
104 {END ADDED by fduenas 15-06-2006}
105 procedure Despose(var Handle: PZMySQLConnect);
107 function GetAffectedRows(Handle: PZMySQLConnect): Int64;
108 {ADDED by EgonHugeist}
109 function GetConnectionCharacterSet(Handle: PMYSQL): PAnsiChar;// char_set_name
110 procedure Close(Handle: PZMySQLConnect);
111 function Connect(Handle: PZMySQLConnect; const Host, User, Password: PAnsiChar): PZMySQLConnect;
112 function CreateDatabase(Handle: PZMySQLConnect; const Database: PAnsiChar): Integer;
113 procedure SeekData(Res: PZMySQLResult; Offset: Cardinal);
114 procedure Debug(Debug: PAnsiChar);
115 function DropDatabase(Handle: PZMySQLConnect; const Database: PAnsiChar): Integer;
116 function DumpDebugInfo(Handle: PZMySQLConnect): Integer;
118 function GetLastErrorCode(Handle: PZMySQLConnect): Integer;
119 function GetLastError(Handle: PZMySQLConnect): PAnsiChar;
120 function FetchField(Res: PZMySQLResult): PZMySQLField;
121 // fetch_field_direct
123 function FetchLengths(Res: PZMySQLResult): PULong;
124 function FetchRow(Res: PZMySQLResult): PZMySQLRow;
125 function SeekField(Res: PZMySQLResult; Offset: Cardinal): Cardinal;
127 procedure FreeResult(Res: PZMySQLResult);
128 function GetClientInfo: PAnsiChar;
129 function GetHostInfo(Handle: PZMySQLConnect): PAnsiChar;
130 function GetProtoInfo(Handle: PZMySQLConnect): Cardinal;
131 function GetServerInfo(Handle: PZMySQLConnect): PAnsiChar;
133 function Init(const Handle: PZMySQLConnect): PZMySQLConnect;
134 function GetLastInsertID (Handle: PZMySQLConnect): Int64;
135 function Kill(Handle: PZMySQLConnect; Pid: LongInt): Integer;
136 function GetBindOffsets: MYSQL_BINDOFFSETS;
137 function GetListDatabases(Handle: PZMySQLConnect; Wild: PAnsiChar): PZMySQLResult;
138 function GetListFields(Handle: PZMySQLConnect; const Table, Wild: PAnsiChar): PZMySQLResult;
139 function GetListProcesses(Handle: PZMySQLConnect): PZMySQLResult;
140 function GetListTables(Handle: PZMySQLConnect; const Wild: PAnsiChar): PZMySQLResult;
142 function GetNumRows(Res: PZMySQLResult): Int64;
143 function SetOptions(Handle: PZMySQLConnect; Option: TMySQLOption; const Arg: Pointer): Integer;
144 function Ping(Handle: PZMySQLConnect): Integer;
145 function ExecQuery(Handle: PZMySQLConnect; const Query: PAnsiChar): Integer; overload;
146 function RealConnect(Handle: PZMySQLConnect; const Host, User, Password, Db: PAnsiChar; Port: Cardinal; UnixSocket: PAnsiChar; ClientFlag: Cardinal): PZMySQLConnect;
147 function ExecRealQuery(Handle: PZMySQLConnect; const Query: PAnsiChar; Length: Integer): Integer;
148 function Refresh(Handle: PZMySQLConnect; Options: Cardinal): Integer;
149 function SeekRow(Res: PZMySQLResult; Row: PZMySQLRowOffset): PZMySQLRowOffset;
151 function SelectDatabase(Handle: PZMySQLConnect; const Database: PAnsiChar): Integer;
152 function SslSet(Handle: PZMySQLConnect; const Key, Cert, Ca, Capath, Cipher: PAnsiChar): Integer;
153 function GetStatInfo(Handle: PZMySQLConnect): PAnsiChar;
154 function StoreResult(Handle: PZMySQLConnect): PZMySQLResult;
155 function GetThreadId(Handle: PZMySQLConnect): Cardinal;
156 function UseResult(Handle: PZMySQLConnect): PZMySQLResult;
167 // function GetClientVersion: AnsiString;
169 function Shutdown(Handle: PZMySQLConnect; shutdown_level: TMysqlShutdownLevel = ZPlainMySqlConstants.SHUTDOWN_DEFAULT): Integer; // 2 versions!!
171 function SetAutocommit (Handle: PZMySQLConnect; mode: Boolean): Boolean;
172 function Commit (Handle: PZMySQLConnect): Boolean;
173 //function GetServerVersion (Handle: PZMySQLConnect): AnsiString;
175 function CheckAnotherRowset (Handle: PZMySQLConnect): Boolean;
176 function RetrieveNextRowset (Handle: PZMySQLConnect): Integer;
177 function Rollback (Handle: PZMySQLConnect): Boolean;
178 {ADDED by EgonHugeist}
179 function SetConnectionCharacterSet(Handle: PMYSQL; const csname: PAnsiChar): Integer; // set_character_set returns 0 if valid
181 function GetSQLState (Handle: PZMySQLConnect): AnsiString;
184 function GetPreparedAffectedRows (Handle: PZMySqlPrepStmt): Int64;
186 function StmtAttrSet(stmt: PZMySqlPrepStmt; option: TMysqlStmtAttrType;
188 function BindParameters (Handle: PZMySqlPrepStmt; bindArray: PZMysqlBindArray): Byte;
189 function BindResult (Handle: PZMySqlPrepStmt; bindArray: PZMysqlBindArray): Byte;
190 function ClosePrepStmt (PrepStmtHandle: PZMySqlPrepStmt): PZMySqlPrepStmt;
191 procedure SeekPreparedData(PrepStmtHandle: PZMySqlPrepStmt; Offset: Cardinal);
192 function GetLastPreparedErrorCode(Handle: PZMySqlPrepStmt): Integer;
193 function GetLastPreparedError(Handle: PZMySqlPrepStmt): AnsiString;
194 function ExecuteStmt (Handle: PZMySqlPrepStmt): Integer;
195 function FetchBoundResults (Handle: PZMySqlPrepStmt): Integer;
197 function GetPreparedFieldCount(Handle: PZMySqlPrepStmt): Integer;
198 function FreePreparedResult (Handle: PZMySqlPrepStmt): Byte;
199 function InitializePrepStmt (Handle: PZMySQLConnect): PZMySqlPrepStmt;
200 function GetPreparedInsertID (Handle: PZMySqlPrepStmt): Int64;
201 function GetPreparedNextResult (Handle: PZMySqlPrepStmt): Integer;
202 function GetPreparedNumRows (Handle: PZMySqlPrepStmt): Int64;
203 function GetPreparedBindMarkers (Handle: PZMySqlPrepStmt): Cardinal; // param_count
205 function GetStmtParamMetadata(PrepStmtHandle: PZMySqlPrepStmt): PZMySQLResult; // stmt_param_metadata
206 function PrepareStmt(PrepStmtHandle: PZMySqlPrepStmt; const Query: PAnsiChar; Length: Integer): Integer;
207 function stmt_reset(PrepStmtHandle: PZMySqlPrepStmt): Byte;
208 function GetPreparedMetaData (Handle: PZMySqlPrepStmt): PZMySQLResult;
209 function SeekPreparedRow(Handle: PZMySqlPrepStmt; Row: PZMySQLRowOffset): PZMySQLRowOffset;
211 function SendPreparedLongData(Handle: PZMySqlPrepStmt; parameter_number: Cardinal; const data: PAnsiChar; length: Cardinal): Byte;
212 function GetPreparedSQLState (Handle: PZMySqlPrepStmt): PAnsiChar;
213 function StorePreparedResult (Handle: PZMySqlPrepStmt): Integer;
215 procedure GetCharacterSetInfo(Handle: PZMySQLConnect; CharSetInfo: PMY_CHARSET_INFO);// get_character_set_info since 5.0.10
218 function GetFieldType(Field: PZMySQLField): TMysqlFieldTypes;
219 function GetFieldFlags(Field: PZMySQLField): Integer;
220 function ResultSetExists(Handle: PZMySQLConnect):Boolean;
221 function GetRowCount(Res: PZMySQLResult): Int64;
222 function GetFieldCount(Res: PZMySQLResult): Integer;
223 function GetFieldName(Field: PZMySQLField): PAnsiChar;
224 function GetFieldTable(Field: PZMySQLField): PAnsiChar;
225 function GetFieldOrigTable(Field: PZMySQLField): PAnsiChar;
226 function GetFieldOrigName(Field: PZMySQLField): PAnsiChar;
227 function GetFieldLength(Field: PZMySQLField): ULong;
228 function GetFieldMaxLength(Field: PZMySQLField): Integer;
229 function GetFieldDecimals(Field: PZMySQLField): Integer;
230 function GetFieldCharsetNr(Field: PZMySQLField): UInt;
231 function GetFieldData(Row: PZMySQLRow; Offset: Cardinal): PAnsiChar;
232 procedure SetDriverOptions(Options: TStrings); // changed by tohenk, 2009-10-11
235 {** Implements a base driver for MySQL}
237 { TZMySQLBaseDriver }
239 TZMySQLBaseDriver = class (TZAbstractPlainDriver, IZPlainDriver, IZMySQLPlainDriver)
241 FIsMariaDBDriver: Boolean;
243 MYSQL_API : TZMYSQL_API;
244 ServerArgs: array of PAnsiChar;
245 ServerArgsLen: Integer;
246 IsEmbeddedDriver: Boolean;
247 function GetUnicodeCodePageName: String; override;
248 procedure LoadCodePages; override;
249 procedure LoadApi; override;
250 procedure BuildServerArguments(Options: TStrings);
252 constructor Create(Tokenizer: IZTokenizer);
253 destructor Destroy; override;
255 function IsMariaDBDriver: Boolean;
256 procedure Debug(Debug: PAnsiChar);
257 function DumpDebugInfo(Handle: PZMySQLConnect): Integer;
258 function GetLastError(Handle: PZMySQLConnect): PAnsiChar;
259 function GetLastErrorCode(Handle: PZMySQLConnect): Integer;
260 function Init(const Handle: PZMySQLConnect): PZMySQLConnect; virtual;
261 function GetLastInsertID (Handle: PZMySQLConnect): Int64;
262 procedure Despose(var Handle: PZMySQLConnect);
264 function Connect(Handle: PZMySQLConnect;
265 const Host, User, Password: PAnsiChar): PZMySQLConnect;
266 function RealConnect(Handle: PZMySQLConnect;
267 const Host, User, Password, Db: PAnsiChar; Port: Cardinal;
268 UnixSocket: PAnsiChar; ClientFlag: Cardinal): PZMySQLConnect;
269 procedure Close(Handle: PZMySQLConnect);
271 function ExecQuery(Handle: PZMySQLConnect; const Query: PAnsiChar): Integer; overload;
272 function ExecRealQuery(Handle: PZMySQLConnect; const Query: PAnsiChar;
273 Length: Integer): Integer;
275 function SelectDatabase(Handle: PZMySQLConnect;
276 const Database: PAnsiChar): Integer;
277 function SslSet(Handle: PZMySQLConnect; const Key, Cert, Ca, Capath, Cipher: PAnsiChar): Integer;
278 function CreateDatabase(Handle: PZMySQLConnect;
279 const Database: PAnsiChar): Integer;
280 function DropDatabase(Handle: PZMySQLConnect;
281 const Database: PAnsiChar): Integer;
283 function Shutdown(Handle: PZMySQLConnect; shutdown_level: TMysqlShutdownLevel = ZPlainMySqlConstants.SHUTDOWN_DEFAULT): Integer; // 2 versions!!
284 function SetAutocommit (Handle: PZMySQLConnect; mode: Boolean): Boolean;
285 function Commit (Handle: PZMySQLConnect): Boolean;
286 function CheckAnotherRowset (Handle: PZMySQLConnect): Boolean;
287 function RetrieveNextRowset (Handle: PZMySQLConnect): Integer;
288 function Rollback (Handle: PZMySQLConnect): Boolean;
289 function GetSQLState (Handle: PZMySQLConnect): AnsiString;
291 function StmtAttrSet(stmt: PZMySqlPrepStmt; option: TMysqlStmtAttrType;
293 function GetPreparedAffectedRows (Handle: PZMySqlPrepStmt): Int64;
294 function BindParameters (Handle: PZMySqlPrepStmt; bindArray: PZMysqlBindArray): Byte;
295 function BindResult (Handle: PZMySqlPrepStmt; bindArray: PZMysqlBindArray): Byte;
296 function ClosePrepStmt (PrepStmtHandle: PZMySqlPrepStmt): PZMySqlPrepStmt;
297 procedure SeekPreparedData(PrepStmtHandle: PZMySqlPrepStmt; Offset: Cardinal);
298 function GetLastPreparedErrorCode(Handle: PZMySqlPrepStmt): Integer;
299 function GetLastPreparedError(Handle: PZMySqlPrepStmt): AnsiString;
300 function ExecuteStmt (Handle: PZMySqlPrepStmt): Integer;
301 function FetchBoundResults (Handle: PZMySqlPrepStmt): Integer;
302 function GetPreparedFieldCount(Handle: PZMySqlPrepStmt): Integer;
303 function FreePreparedResult (Handle: PZMySqlPrepStmt): Byte;
304 function InitializePrepStmt (Handle: PZMySQLConnect): PZMySqlPrepStmt;
305 function GetPreparedInsertID (Handle: PZMySqlPrepStmt): Int64;
306 function GetPreparedNextResult (Handle: PZMySqlPrepStmt): Integer;
307 function GetPreparedNumRows (Handle: PZMySqlPrepStmt): Int64;
308 function GetPreparedBindMarkers (Handle: PZMySqlPrepStmt): Cardinal; // param_count
309 function GetStmtParamMetadata(PrepStmtHandle: PZMySqlPrepStmt): PZMySQLResult;
310 function PrepareStmt (PrepStmtHandle: PZMySqlPrepStmt; const Query: PAnsiChar; Length: Integer): Integer;
311 function stmt_reset(PrepStmtHandle: PZMySqlPrepStmt): Byte;
312 function GetPreparedMetaData (Handle: PZMySqlPrepStmt): PZMySQLResult;
313 function SeekPreparedRow(Handle: PZMySqlPrepStmt; Row: PZMySQLRowOffset): PZMySQLRowOffset;
314 function SendPreparedLongData(Handle: PZMySqlPrepStmt; parameter_number: Cardinal; const data: PAnsiChar; length: Cardinal): Byte;
315 function GetPreparedSQLState (Handle: PZMySqlPrepStmt): PAnsiChar;
316 function StorePreparedResult (Handle: PZMySqlPrepStmt): Integer;
317 procedure GetCharacterSetInfo(Handle: PZMySQLConnect; CharSetInfo: PMY_CHARSET_INFO);
319 function GetBindOffsets: MYSQL_BINDOFFSETS;
320 function Refresh(Handle: PZMySQLConnect; Options: Cardinal): Integer;
321 function Kill(Handle: PZMySQLConnect; Pid: LongInt): Integer;
322 function Ping(Handle: PZMySQLConnect): Integer;
324 function GetStatInfo(Handle: PZMySQLConnect): PAnsiChar;
325 function SetOptions(Handle: PZMySQLConnect; Option: TMySQLOption;
326 const Arg: Pointer): Integer;
327 function EscapeString(Handle: Pointer; const Value: RawByteString;
328 ConSettings: PZConSettings; WasEncoded: Boolean = False): RawByteString; override;
329 function GetServerInfo(Handle: PZMySQLConnect): PAnsiChar;
330 function GetClientInfo: PAnsiChar;
331 function GetHostInfo(Handle: PZMySQLConnect): PAnsiChar;
332 function GetProtoInfo(Handle: PZMySQLConnect): Cardinal;
333 function GetThreadId(Handle: PZMySQLConnect): Cardinal;
334 {ADDED by fduenas 15-06-2006}
335 function GetClientVersion: Integer;
336 function GetServerVersion(Handle: PZMySQLConnect): Integer;
337 {END ADDED by fduenas 15-06-2006}
338 function GetListDatabases(Handle: PZMySQLConnect;
339 Wild: PAnsiChar): PZMySQLResult;
340 function GetListTables(Handle: PZMySQLConnect;
341 const Wild: PAnsiChar): PZMySQLResult;
342 function GetNumRows(Res: PZMySQLResult): Int64;
343 function GetListFields(Handle: PZMySQLConnect;
344 const Table, Wild: PAnsiChar): PZMySQLResult;
345 function GetListProcesses(Handle: PZMySQLConnect): PZMySQLResult;
347 function StoreResult(Handle: PZMySQLConnect): PZMySQLResult;
348 function UseResult(Handle: PZMySQLConnect): PZMySQLResult;
349 procedure FreeResult(Res: PZMySQLResult);
350 function GetAffectedRows(Handle: PZMySQLConnect): Int64;
351 {ADDED by EgonHugeist}
352 function GetConnectionCharacterSet(Handle: PMYSQL): PAnsiChar;// char_set_name
353 function SetConnectionCharacterSet(Handle: PMYSQL; const csname: PAnsiChar): Integer; // set_character_set Returns 0 if valid
355 function FetchRow(Res: PZMySQLResult): PZMySQLRow;
356 function FetchLengths(Res: PZMySQLResult): PULong;
357 function FetchField(Res: PZMySQLResult): PZMySQLField;
359 procedure SeekData(Res: PZMySQLResult; Offset: Cardinal);
360 function SeekRow(Res: PZMySQLResult; Row: PZMySQLRowOffset):
362 function SeekField(Res: PZMySQLResult; Offset: Cardinal): Cardinal;
364 function GetFieldType(Field: PZMySQLField): TMysqlFieldTypes;
365 function GetFieldFlags(Field: PZMySQLField): Integer;
366 function ResultSetExists(Handle: PZMySQLConnect):Boolean;
367 function GetRowCount(Res: PZMySQLResult): Int64;
368 function GetFieldCount(Res: PZMySQLResult): Integer;
369 function GetFieldName(Field: PZMySQLField): PAnsiChar;
370 function GetFieldTable(Field: PZMySQLField): PAnsiChar;
371 function GetFieldOrigTable(Field: PZMySQLField): PAnsiChar;
372 function GetFieldOrigName(Field: PZMySQLField): PAnsiChar;
373 function GetFieldLength(Field: PZMySQLField): ULong;
374 function GetFieldMaxLength(Field: PZMySQLField): Integer;
375 function GetFieldDecimals(Field: PZMySQLField): Integer;
376 function GetFieldCharsetNr(Field: PZMySQLField): UInt;
377 function GetFieldData(Row: PZMySQLRow; Offset: Cardinal): PAnsiChar;
378 procedure SetDriverOptions(Options: TStrings); virtual; // changed by tohenk, 2009-10-11
381 {** Implements a driver for MySQL 4.1 }
383 { TZNewMySQL41PlainDriver }
385 TZMySQL41PlainDriver = class (TZMysqlBaseDriver)
387 function Clone: IZPlainDriver; override;
389 constructor Create(Tokenizer: IZTokenizer);
390 function GetProtocol: string; override;
391 function GetDescription: string; override;
394 {** Implements a driver for MySQL 4.1 }
396 { TZNewMySQLD41PlainDriver }
398 TZMySQLD41PlainDriver = class (TZMySQL41PlainDriver)
400 function Clone: IZPlainDriver; override;
402 constructor Create(Tokenizer: IZTokenizer);
403 function GetProtocol: string; override;
404 function GetDescription: string; override;
407 { TZNewMySQL5PlainDriver }
409 TZMySQL5PlainDriver = class (TZMysqlBaseDriver)
411 function Clone: IZPlainDriver; override;
413 procedure LoadApi; override;
414 procedure LoadCodePages; override;
416 constructor Create(Tokenizer: IZTokenizer);
417 function GetProtocol: string; override;
418 function GetDescription: string; override;
421 { TZNewMySQLD5PlainDriver }
423 TZMySQLD5PlainDriver = class (TZMySQL5PlainDriver)
425 function Clone: IZPlainDriver; override;
427 constructor Create(Tokenizer: IZTokenizer);
428 function GetProtocol: string; override;
429 function GetDescription: string; override;
432 { TZMariaDB5PlainDriver }
434 TZMariaDB5PlainDriver = class (TZMySQL5PlainDriver)
436 function Clone: IZPlainDriver; override;
438 constructor Create(Tokenizer: IZTokenizer);
439 function GetProtocol: string; override;
440 function GetDescription: string; override;
445 uses SysUtils, ZPlainLoader, ZEncoding
446 {$IFDEF WITH_UNITANSISTRINGS}, AnsiStrings{$ENDIF};
448 { TZMySQLPlainBaseDriver }
449 function TZMySQLBaseDriver.GetUnicodeCodePageName: String;
454 procedure TZMySQLBaseDriver.LoadCodePages;
458 AddCodePage('big5', 1, ceAnsi, zCP_Big5, '', 2); {Big5 Traditional Chinese}
459 AddCodePage('ujis', 10, ceAnsi, zCP_EUC_JP, '', 3); {EUC-JP Japanese}
460 AddCodePage('sjis', 11, ceAnsi, zCP_SHIFTJS, '', 2); {Shift-JIS Japanese}
461 AddCodePage('gbk', 19, ceAnsi, zCP_GB2312, '', 2); {GBK Simplified Chinese}
462 AddCodePage('utf8', 22, ceUTF8, zCP_UTF8, '', 3); {UTF-8 Unicode}
463 AddCodePage('ucs2', 23, ceUTF16, zCP_UTF16, 'utf8', 2); {UCS-2 Unicode}
464 AddCodePage('euckr', 14, ceAnsi, zCP_EUCKR, '', 2); {EUC-KR Korean}
465 AddCodePage('gb2312', 16, ceAnsi, zCP_GB2312, '', 2); {GB2312 Simplified Chinese}
466 AddCodePage('cp932', 35, ceAnsi, zCP_SHIFTJS, '', 2); {SJIS for Windows Japanese}
467 AddCodePage('eucjpms', 36, ceAnsi, $ffff, '', 3); {UJIS for Windows Japanese}
469 AddCodePage('dec8', 2); {DEC West European}
470 AddCodePage('cp850', 3, ceAnsi, zCP_DOS850); {DOS West European}
471 AddCodePage('hp8', 4); {HP West European}
472 AddCodePage('koi8r', 5, ceAnsi, zCP_KOI8R); {KOI8-R Relcom Russian}
473 AddCodePage('latin1', 6, ceAnsi, zCP_WIN1252); {cp1252 West European}
474 AddCodePage('latin2', 7, ceAnsi, zCP_L2_ISO_8859_2); {ISO 8859-2 Central European}
475 AddCodePage('swe7', 8, ceAnsi, zCP_x_IA5_Swedish); {7bit Swedish}
476 AddCodePage('ascii', 9, ceAnsi, zCP_us_ascii); {US ASCII}
477 AddCodePage('hebrew', 12, ceAnsi, zCP_L8_ISO_8859_8); {ISO 8859-8 Hebrew}
478 AddCodePage('tis620', 13, ceAnsi, zCP_IBM_Thai); {TIS620 Thai}
479 AddCodePage('koi8u', 15, ceAnsi, zCP_KOI8U); {KOI8-U Ukrainian}
480 AddCodePage('greek', 17, ceAnsi, zCP_L7_ISO_8859_7); {ISO 8859-7 Greek}
481 AddCodePage('cp1250', 18, ceAnsi, zCP_WIN1250); {Windows Central European}
482 AddCodePage('latin5', 20, ceAnsi, zCP_L5_ISO_8859_9); {ISO 8859-9 Turkish}
483 AddCodePage('armscii8', 21, ceAnsi, zCP_us_ascii); {ARMSCII-8 Armenian}
484 AddCodePage('cp866', 24, ceAnsi, zCP_DOS866); {DOS Russian}
485 AddCodePage('keybcs2', 25); {DOS Kamenicky Czech-Slovak}
486 AddCodePage('macce', 26, ceAnsi, zCP_x_mac_ce); {Mac Central European}
487 AddCodePage('macroman', 27, ceAnsi, zCP_macintosh); {Mac West European}
488 AddCodePage('cp852', 28, ceAnsi, zCP_DOS852); {DOS Central European}
489 AddCodePage('latin7', 29, ceAnsi, zCP_L7_ISO_8859_13); {ISO 8859-13 Baltic}
490 AddCodePage('cp1251', 30, ceAnsi, zCP_WIN1251); {Windows Cyrillic}
491 AddCodePage('cp1256', 31, ceAnsi, cCP_WIN1256); {Windows Arabic}
492 AddCodePage('cp1257', 32, ceAnsi, zCP_WIN1257); {Windows Baltic}
493 AddCodePage('binary', 33); {Binary pseudo charset}
494 AddCodePage('geostd8', 34); {GEOSTD8 Georgian}
497 procedure TZMySQLBaseDriver.LoadApi;
499 { ************** Load adresses of API Functions ************* }
502 @MYSQL_API.mysql_affected_rows := GetAddress('mysql_affected_rows');
503 @MYSQL_API.mysql_character_set_name := GetAddress('mysql_character_set_name');
504 @MYSQL_API.mysql_close := GetAddress('mysql_close');
505 @MYSQL_API.mysql_connect := GetAddress('mysql_connect');
506 @MYSQL_API.mysql_create_db := GetAddress('mysql_create_db');
507 @MYSQL_API.mysql_data_seek := GetAddress('mysql_data_seek');
508 @MYSQL_API.mysql_debug := GetAddress('mysql_debug');
509 @MYSQL_API.mysql_drop_db := GetAddress('mysql_drop_db');
510 @MYSQL_API.mysql_dump_debug_info := GetAddress('mysql_dump_debug_info');
511 @MYSQL_API.mysql_eof := GetAddress('mysql_eof');
512 @MYSQL_API.mysql_errno := GetAddress('mysql_errno');
513 @MYSQL_API.mysql_error := GetAddress('mysql_error');
514 @MYSQL_API.mysql_escape_string := GetAddress('mysql_escape_string');
515 @MYSQL_API.mysql_fetch_field := GetAddress('mysql_fetch_field');
516 @MYSQL_API.mysql_fetch_field_direct := GetAddress('mysql_fetch_field_direct');
517 @MYSQL_API.mysql_fetch_fields := GetAddress('mysql_fetch_fields');
518 @MYSQL_API.mysql_fetch_lengths := GetAddress('mysql_fetch_lengths');
519 @MYSQL_API.mysql_fetch_row := GetAddress('mysql_fetch_row');
520 @MYSQL_API.mysql_field_seek := GetAddress('mysql_field_seek');
521 @MYSQL_API.mysql_field_tell := GetAddress('mysql_field_tell');
522 @MYSQL_API.mysql_free_result := GetAddress('mysql_free_result');
523 @MYSQL_API.mysql_get_client_info := GetAddress('mysql_get_client_info');
524 @MYSQL_API.mysql_get_host_info := GetAddress('mysql_get_host_info');
525 @MYSQL_API.mysql_get_proto_info := GetAddress('mysql_get_proto_info');
526 @MYSQL_API.mysql_get_server_info := GetAddress('mysql_get_server_info');
527 @MYSQL_API.mysql_info := GetAddress('mysql_info');
528 @MYSQL_API.mysql_init := GetAddress('mysql_init');
529 @MYSQL_API.mysql_library_end := GetAddress('mysql_library_end');
530 @MYSQL_API.mysql_insert_id := GetAddress('mysql_insert_id');
531 @MYSQL_API.mysql_kill := GetAddress('mysql_kill');
532 @MYSQL_API.mysql_list_dbs := GetAddress('mysql_list_dbs');
533 @MYSQL_API.mysql_list_fields := GetAddress('mysql_list_fields');
534 @MYSQL_API.mysql_list_processes := GetAddress('mysql_list_processes');
535 @MYSQL_API.mysql_list_tables := GetAddress('mysql_list_tables');
536 @MYSQL_API.mysql_num_fields := GetAddress('mysql_num_fields');
537 @MYSQL_API.mysql_num_rows := GetAddress('mysql_num_rows');
538 @MYSQL_API.mysql_options := GetAddress('mysql_options');
539 @MYSQL_API.mysql_ping := GetAddress('mysql_ping');
540 @MYSQL_API.mysql_query := GetAddress('mysql_query');
541 @MYSQL_API.mysql_real_connect := GetAddress('mysql_real_connect');
542 @MYSQL_API.mysql_real_escape_string := GetAddress('mysql_real_escape_string');
543 @MYSQL_API.mysql_real_query := GetAddress('mysql_real_query');
544 @MYSQL_API.mysql_refresh := GetAddress('mysql_refresh');
545 @MYSQL_API.mysql_row_seek := GetAddress('mysql_row_seek');
546 @MYSQL_API.mysql_row_tell := GetAddress('mysql_row_tell');
547 @MYSQL_API.mysql_select_db := GetAddress('mysql_select_db');
548 @MYSQL_API.mysql_shutdown := GetAddress('mysql_shutdown');
549 @MYSQL_API.mysql_ssl_set := GetAddress('mysql_ssl_set');
550 @MYSQL_API.mysql_stat := GetAddress('mysql_stat');
551 @MYSQL_API.mysql_store_result := GetAddress('mysql_store_result');
552 @MYSQL_API.mysql_thread_id := GetAddress('mysql_thread_id');
553 @MYSQL_API.mysql_use_result := GetAddress('mysql_use_result');
555 @MYSQL_API.my_init := GetAddress('my_init');
556 @MYSQL_API.mysql_thread_init := GetAddress('mysql_thread_init');
557 @MYSQL_API.mysql_thread_end := GetAddress('mysql_thread_end');
558 @MYSQL_API.mysql_thread_safe := GetAddress('mysql_thread_safe');
560 @MYSQL_API.mysql_server_init := GetAddress('mysql_server_init');
561 @MYSQL_API.mysql_server_end := GetAddress('mysql_server_end');
563 @MYSQL_API.mysql_change_user := GetAddress('mysql_change_user');
564 @MYSQL_API.mysql_field_count := GetAddress('mysql_field_count');
566 @MYSQL_API.mysql_get_client_version := GetAddress('mysql_get_client_version');
568 @MYSQL_API.mysql_send_query := GetAddress('mysql_send_query');
569 @MYSQL_API.mysql_read_query_result := GetAddress('mysql_read_query_result');
571 @MYSQL_API.mysql_autocommit := GetAddress('mysql_autocommit');
572 @MYSQL_API.mysql_commit := GetAddress('mysql_commit');
573 @MYSQL_API.mysql_get_server_version := GetAddress('mysql_get_server_version');
574 @MYSQL_API.mysql_hex_string := GetAddress('mysql_hex_string');
575 @MYSQL_API.mysql_more_results := GetAddress('mysql_more_results');
576 @MYSQL_API.mysql_next_result := GetAddress('mysql_next_result');
577 @MYSQL_API.mysql_rollback := GetAddress('mysql_rollback');
578 @MYSQL_API.mysql_set_character_set := GetAddress('mysql_set_character_set');
579 @MYSQL_API.mysql_set_server_option := GetAddress('mysql_set_server_option');
580 @MYSQL_API.mysql_sqlstate := GetAddress('mysql_sqlstate');
581 @MYSQL_API.mysql_warning_count := GetAddress('mysql_warning_count');
582 @MYSQL_API.mysql_stmt_affected_rows := GetAddress('mysql_stmt_affected_rows');
583 @MYSQL_API.mysql_stmt_attr_get := GetAddress('mysql_stmt_attr_get');
584 @MYSQL_API.mysql_stmt_attr_set := GetAddress('mysql_stmt_attr_set'); //uses ulong
585 @MYSQL_API.mysql_stmt_attr_set517UP := GetAddress('mysql_stmt_attr_set'); //uses mybool
586 @MYSQL_API.mysql_stmt_bind_param := GetAddress('mysql_stmt_bind_param');
587 @MYSQL_API.mysql_stmt_bind_result := GetAddress('mysql_stmt_bind_result');
588 @MYSQL_API.mysql_stmt_close := GetAddress('mysql_stmt_close');
589 @MYSQL_API.mysql_stmt_data_seek := GetAddress('mysql_stmt_data_seek');
590 @MYSQL_API.mysql_stmt_errno := GetAddress('mysql_stmt_errno');
591 @MYSQL_API.mysql_stmt_error := GetAddress('mysql_stmt_error');
592 @MYSQL_API.mysql_stmt_execute := GetAddress('mysql_stmt_execute');
593 @MYSQL_API.mysql_stmt_fetch := GetAddress('mysql_stmt_fetch');
594 @MYSQL_API.mysql_stmt_fetch_column := GetAddress('mysql_stmt_fetch_column');
595 @MYSQL_API.mysql_stmt_field_count := GetAddress('mysql_stmt_field_count');
596 @MYSQL_API.mysql_stmt_free_result := GetAddress('mysql_stmt_free_result');
597 @MYSQL_API.mysql_stmt_init := GetAddress('mysql_stmt_init');
598 @MYSQL_API.mysql_stmt_insert_id := GetAddress('mysql_stmt_insert_id');
599 @MYSQL_API.mysql_stmt_num_rows := GetAddress('mysql_stmt_num_rows');
600 @MYSQL_API.mysql_stmt_param_count := GetAddress('mysql_stmt_param_count');
601 @MYSQL_API.mysql_stmt_param_metadata := GetAddress('mysql_stmt_param_metadata');
602 @MYSQL_API.mysql_stmt_prepare := GetAddress('mysql_stmt_prepare');
603 @MYSQL_API.mysql_stmt_reset := GetAddress('mysql_stmt_reset');
604 @MYSQL_API.mysql_stmt_result_metadata := GetAddress('mysql_stmt_result_metadata');
605 @MYSQL_API.mysql_stmt_row_seek := GetAddress('mysql_stmt_row_seek');
606 @MYSQL_API.mysql_stmt_row_tell := GetAddress('mysql_stmt_row_tell');
607 @MYSQL_API.mysql_stmt_send_long_data := GetAddress('mysql_stmt_send_long_data');
608 @MYSQL_API.mysql_stmt_sqlstate := GetAddress('mysql_stmt_sqlstate');
609 @MYSQL_API.mysql_stmt_store_result := GetAddress('mysql_stmt_store_result');
613 procedure TZMySQLBaseDriver.BuildServerArguments(Options: TStrings);
615 TmpList: TStringList;
618 TmpList := TStringList.Create;
620 TmpList.Add(ParamStr(0));
621 for i := 0 to Options.Count - 1 do
622 if SameText(SERVER_ARGUMENTS_KEY_PREFIX,
623 Copy(Options.Names[i], 1,
624 Length(SERVER_ARGUMENTS_KEY_PREFIX))) then
625 TmpList.Add(Options.ValueFromIndex[i]);
626 //Check if DataDir is specified, if not, then add it to the Arguments List
627 if TmpList.Values['--datadir'] = '' then
628 TmpList.Add('--datadir='+EMBEDDED_DEFAULT_DATA_DIR);
630 for i := 0 to ServerArgsLen - 1 do
631 {$IFDEF WITH_STRDISPOSE_DEPRECATED}AnsiStrings.{$ENDIF}StrDispose(ServerArgs[i]);
632 ServerArgsLen := TmpList.Count;
633 SetLength(ServerArgs, ServerArgsLen);
634 for i := 0 to ServerArgsLen - 1 do
636 ServerArgs[i] := {$IFDEF WITH_STRNEW_DEPRECATED}AnsiStrings.{$ENDIF}StrNew(PAnsiChar(UTF8String(TmpList[i])));
638 ServerArgs[i] := StrNew(PAnsiChar(TmpList[i]));
645 constructor TZMySQLBaseDriver.Create(Tokenizer: IZTokenizer);
648 FLoader := TZNativeLibraryLoader.Create([]);
650 FTokenizer := Tokenizer;
651 {$IFNDEF MYSQL_STRICT_DLL_LOADING}
653 FLoader.AddLocation(WINDOWS_DLL_LOCATION);
655 FLoader.AddLocation(LINUX_DLL_LOCATION);
659 SetLength(ServerArgs, ServerArgsLen);
660 IsEmbeddedDriver := False;
664 destructor TZMySQLBaseDriver.Destroy;
668 for i := 0 to ServerArgsLen - 1 do
669 {$IFDEF WITH_STRDISPOSE_DEPRECATED}AnsiStrings.{$ENDIF}StrDispose(ServerArgs[i]);
671 if (FLoader.Loaded) then
672 if (@ MYSQL_API.mysql_library_end <> nil) then
673 MYSQL_API.mysql_library_end //since 5.0.3
675 if (@ MYSQL_API.mysql_server_end <> nil) then
676 MYSQL_API.mysql_server_end; //deprected since 5.0.3
680 function TZMySQLBaseDriver.IsMariaDBDriver: Boolean;
682 Result := FIsMariaDBDriver;
685 procedure TZMySQLBaseDriver.Close(Handle: PZMySQLConnect);
687 MYSQL_API.mysql_close(Handle);
690 function TZMySQLBaseDriver.Connect(Handle: PZMySQLConnect; const Host,
691 User, Password: PAnsiChar): PZMySQLConnect;
693 Result := MYSQL_API.mysql_connect(Handle, Host, User, Password);
696 function TZMySQLBaseDriver.SslSet(Handle: PZMySQLConnect;
697 const Key, Cert, Ca, Capath, Cipher: PAnsiChar): Integer;
699 Result := MYSQL_API.mysql_ssl_set(Handle, Key, Cert, Ca, Capath, Cipher);
702 function TZMySQLBaseDriver.CreateDatabase(Handle: PZMySQLConnect;
703 const Database: PAnsiChar): Integer;
705 Result := MYSQL_API.mysql_create_db(Handle, Database);
708 procedure TZMySQLBaseDriver.Debug(Debug: PAnsiChar);
710 MYSQL_API.mysql_debug(Debug);
713 function TZMySQLBaseDriver.DropDatabase(Handle: PZMySQLConnect;
714 const Database: PAnsiChar): Integer;
716 Result := MYSQL_API.mysql_drop_db(Handle, Database);
719 function TZMySQLBaseDriver.DumpDebugInfo(Handle: PZMySQLConnect): Integer;
721 Result := MYSQL_API.mysql_dump_debug_info(Handle);
724 function TZMySQLBaseDriver.ExecQuery(Handle: PZMySQLConnect;
725 const Query: PAnsiChar): Integer;
727 Result := MYSQL_API.mysql_query(Handle, Query);
730 function TZMySQLBaseDriver.ExecRealQuery(Handle: PZMySQLConnect;
731 const Query: PAnsiChar; Length: Integer): Integer;
733 Result := MYSQL_API.mysql_real_query(Handle, Query, Length);
736 function TZMySQLBaseDriver.FetchField(Res: PZMySQLResult): PZMySQLField;
738 Result := MYSQL_API.mysql_fetch_field(Res);
741 function TZMySQLBaseDriver.FetchLengths(Res: PZMySQLResult): PULong;
743 Result := MYSQL_API.mysql_fetch_lengths(Res);
746 function TZMySQLBaseDriver.FetchRow(Res: PZMySQLResult): PZMySQLRow;
748 Result := MYSQL_API.mysql_fetch_row(Res);
751 procedure TZMySQLBaseDriver.FreeResult(Res: PZMySQLResult);
753 MYSQL_API.mysql_free_result(Res);
756 function TZMySQLBaseDriver.GetAffectedRows(Handle: PZMySQLConnect): Int64;
758 Result := MYSQL_API.mysql_affected_rows(Handle);
762 EgonHugeist: Get CharacterSet of current Connection
763 Returns the default character set name for the current connection.
765 function TZMySQLBaseDriver.GetConnectionCharacterSet(Handle: PMYSQL): PAnsiChar;// char_set_name
767 if Assigned(MYSQL_API.mysql_character_set_name) then
768 Result := MYSQL_API.mysql_character_set_name(Handle)
774 EgonHugeist: This function is used to set the default character set for the
775 current connection. The string csname specifies a valid character set name.
776 The connection collation becomes the default collation of the character set.
777 This function works like the SET NAMES statement, but also sets the value
778 of mysql->charset, and thus affects the character set
779 used by mysql_real_escape_string()
781 function TZMySQLBaseDriver.SetConnectionCharacterSet(Handle: PMYSQL;
782 const csname: PAnsiChar): Integer; // set_character_set Returns 0 if valid
784 Result := MYSQL_API.mysql_set_character_set(Handle, csName);
787 function TZMySQLBaseDriver.GetClientInfo: PAnsiChar;
789 Result := MYSQL_API.mysql_get_client_info;
792 function TZMySQLBaseDriver.EscapeString(Handle: Pointer; const Value: RawByteString;
793 ConSettings: PZConSettings; WasEncoded: Boolean = False): RawByteString;
795 Len, outlength: integer;
796 Outbuffer: RawByteString;
797 TempValue: RawByteString;
805 TempValue := ZPlainString(Value, ConSettings); //check encoding too
807 Len := Length(TempValue);
808 Setlength(Outbuffer,Len*2+1);
810 OutLength := MYSQL_API.mysql_escape_string(PAnsiChar(OutBuffer), PAnsiChar(TempValue), Len)
812 OutLength := MYSQL_API.mysql_real_escape_string(Handle, PAnsiChar(OutBuffer), PAnsiChar(TempValue), Len);
813 Setlength(Outbuffer,OutLength);
814 Result := #39+Outbuffer+#39;
817 function TZMySQLBaseDriver.GetHostInfo(Handle: PZMySQLConnect): PAnsiChar;
819 Result := MYSQL_API.mysql_get_host_info(Handle);
822 function TZMySQLBaseDriver.GetListDatabases(Handle: PZMySQLConnect;
823 Wild: PAnsiChar): PZMySQLResult;
825 Result := MYSQL_API.mysql_list_dbs(Handle, Wild);
828 function TZMySQLBaseDriver.GetListFields(Handle: PZMySQLConnect;
829 const Table, Wild: PAnsiChar): PZMySQLResult;
831 Result := MYSQL_API.mysql_list_fields(Handle, Table, Wild);
834 function TZMySQLBaseDriver.GetListProcesses(
835 Handle: PZMySQLConnect): PZMySQLResult;
837 Result := MYSQL_API.mysql_list_processes(Handle);
840 function TZMySQLBaseDriver.GetListTables(Handle: PZMySQLConnect;
841 const Wild: PAnsiChar): PZMySQLResult;
843 Result := MYSQL_API.mysql_list_tables(Handle, Wild);
846 function TZMySQLBaseDriver.GetNumRows(Res: PZMySQLResult): Int64;
851 Result := MYSQL_API.mysql_num_rows (Res);
854 function TZMySQLBaseDriver.GetProtoInfo(Handle: PZMySQLConnect): Cardinal;
856 Result := MYSQL_API.mysql_get_proto_info(Handle);
859 function TZMySQLBaseDriver.GetServerInfo(Handle: PZMySQLConnect): PAnsiChar;
861 Result := MYSQL_API.mysql_get_server_info(Handle);
864 function TZMySQLBaseDriver.GetStatInfo(Handle: PZMySQLConnect): PAnsiChar;
866 Result := MYSQL_API.mysql_stat(Handle);
869 function TZMySQLBaseDriver.GetThreadId(Handle: PZMySQLConnect): Cardinal;
871 Result := MYSQL_API.mysql_thread_id(Handle);
874 function TZMySQLBaseDriver.Init(const Handle: PZMySQLConnect): PZMySQLConnect;
876 ClientInfo: PAnsiChar;
879 if @MYSQL_API.mysql_server_init <> nil then
880 MYSQL_API.mysql_server_init(ServerArgsLen, ServerArgs, @SERVER_GROUPS);
881 Result := MYSQL_API.mysql_init(Handle);
882 ClientInfo := GetClientInfo;
883 L := {$IFDEF WITH_STRLEN_DEPRECATED}AnsiStrings.{$ENDIF}StrLen(ClientInfo);
884 FIsMariaDBDriver := CompareMem(ClientInfo+L-7, PAnsiChar('MariaDB'), 7);
887 function TZMySQLBaseDriver.GetLastInsertID(Handle: PZMySQLConnect): Int64;
889 Result := MYSQL_API.mysql_insert_id(PMYSQL(Handle));
892 procedure TZMySQLBaseDriver.Despose(var Handle: PZMySQLConnect);
897 function TZMySQLBaseDriver.Kill(Handle: PZMySQLConnect; Pid: LongInt): Integer;
899 Result := MYSQL_API.mysql_kill(Handle, Pid);
902 function TZMySQLBaseDriver.Ping(Handle: PZMySQLConnect): Integer;
904 Result := MYSQL_API.mysql_ping(Handle);
907 function TZMySQLBaseDriver.RealConnect(Handle: PZMySQLConnect;
908 const Host, User, Password, Db: PAnsiChar; Port: Cardinal; UnixSocket: PAnsiChar;
909 ClientFlag: Cardinal): PZMySQLConnect;
911 Result := MYSQL_API.mysql_real_connect(Handle, Host, User, Password, Db,
912 Port, UnixSocket, ClientFlag);
915 {function TZMySQLBaseDriver.GetRealEscapeString(Handle: PZMySQLConnect; StrTo, StrFrom: PAnsiChar;
916 Length: Cardinal): Cardinal;
918 Result := MYSQL_API.mysql_real_escape_string(Handle, StrTo, StrFrom, Length);
921 function TZMySQLBaseDriver.Refresh(Handle: PZMySQLConnect;
922 Options: Cardinal): Integer;
924 Result := MYSQL_API.mysql_refresh(Handle, Options);
927 procedure TZMySQLBaseDriver.SeekData(Res: PZMySQLResult;
930 MYSQL_API.mysql_data_seek(Res, Offset);
933 function TZMySQLBaseDriver.SeekField(Res: PZMySQLResult;
934 Offset: Cardinal): Cardinal;
936 Result := MYSQL_API.mysql_field_seek(Res, Offset);
939 function TZMySQLBaseDriver.SeekRow(Res: PZMySQLResult;
940 Row: PZMySQLRowOffset): PZMySQLRowOffset;
942 Result := MYSQL_API.mysql_row_seek(Res, Row);
945 function TZMySQLBaseDriver.SelectDatabase(Handle: PZMySQLConnect;
946 const Database: PAnsiChar): Integer;
948 Result := MYSQL_API.mysql_select_db(Handle, Database);
951 function TZMySQLBaseDriver.SetOptions(Handle: PZMySQLConnect;
952 Option: TMySQLOption; const Arg: Pointer): Integer;
954 Result := MYSQL_API.mysql_options(Handle,TMySqlOption(Option), Arg);
957 function TZMySQLBaseDriver.Shutdown(Handle: PZMySQLConnect; shutdown_level: TMysqlShutdownLevel = ZPlainMySqlConstants.SHUTDOWN_DEFAULT): Integer;
959 Result := MYSQL_API.mysql_shutdown(Handle,shutdown_level);
962 function TZMySQLBaseDriver.SetAutocommit(Handle: PZMySQLConnect; mode: Boolean): Boolean;
964 Result := MYSQL_API.mysql_autocommit(PMYSQL(Handle), Byte(Ord(Mode))) = 0;
967 function TZMySQLBaseDriver.Commit(Handle: PZMySQLConnect): Boolean;
969 Result := MYSQL_API.mysql_commit(PMYSQL(Handle)) = 0;
972 function TZMySQLBaseDriver.CheckAnotherRowset(Handle: PZMySQLConnect): Boolean;
974 Result := MYSQL_API.mysql_more_results (PMYSQL(Handle)) <> 0;
977 function TZMySQLBaseDriver.RetrieveNextRowset(Handle: PZMySQLConnect): Integer;
979 Result := MYSQL_API.mysql_next_result (PMYSQL(Handle));
982 function TZMySQLBaseDriver.Rollback (Handle: PZMySQLConnect): Boolean;
984 Result := MYSQL_API.mysql_rollback(PMYSQL(Handle)) = 0;
987 function TZMySQLBaseDriver.GetSQLState(Handle: PZMySQLConnect): AnsiString;
989 Result := MYSQL_API.mysql_sqlstate (PMYSQL(Handle));
992 function TZMySQLBaseDriver.StmtAttrSet(stmt: PZMySqlPrepStmt;
993 option: TMysqlStmtAttrType; arg: Pointer): Byte;
995 //http://dev.mysql.com/doc/refman/4.1/en/mysql-stmt-attr-set.html
996 //http://dev.mysql.com/doc/refman/5.0/en/mysql-stmt-attr-set.html
997 if MYSQL_API.mysql_get_client_version >= 50107 then
998 Result := MYSQL_API.mysql_stmt_attr_set517up(PMYSQL_STMT(stmt),option,arg)
999 else //avoid stack crashs !
1000 Result := MYSQL_API.mysql_stmt_attr_set(PMYSQL_STMT(stmt),option,arg);
1003 function TZMySQLBaseDriver.GetPreparedAffectedRows(Handle: PZMySqlPrepStmt): Int64;
1005 Result := MYSQL_API.mysql_stmt_affected_rows (PMYSQL_STMT(Handle));
1008 function TZMySQLBaseDriver.BindParameters(Handle: PZMySqlPrepStmt; bindArray: PZMysqlBindArray): Byte;
1010 Result := MYSQL_API.mysql_stmt_bind_param (PMYSQL_STMT(Handle), pointer(bindArray));
1013 function TZMySQLBaseDriver.BindResult(Handle: PZMySqlPrepStmt; bindArray: PZMysqlBindArray): Byte;
1015 Result := MYSQL_API.mysql_stmt_bind_result (PMYSQL_STMT(Handle), pointer(bindArray));
1018 function TZMySQLBaseDriver.ClosePrepStmt (PrepStmtHandle: PZMySqlPrepStmt): PZMySqlPrepStmt;
1020 if (MYSQL_API.mysql_stmt_close(PMYSQL_STMT(PrepStmtHandle)) = 0) then
1023 Result := PrepStmtHandle;
1026 procedure TZMySQLBaseDriver.SeekPreparedData(PrepStmtHandle: PZMySqlPrepStmt; Offset: Cardinal);
1028 MYSQL_API.mysql_stmt_data_seek(PMYSQL_STMT(PrepStmtHandle), Offset);
1031 function TZMySQLBaseDriver.GetLastPreparedErrorCode(Handle: PZMySqlPrepStmt):Integer;
1033 Result := MYSQL_API.mysql_stmt_errno(PMYSQL_STMT(Handle));
1036 function TZMySQLBaseDriver.GetLastPreparedError(Handle: PZMySqlPrepStmt):AnsiString;
1038 Result := MYSQL_API.mysql_stmt_error(PMYSQL_STMT(Handle));
1041 function TZMySQLBaseDriver.ExecuteStmt(Handle: PZMySqlPrepStmt): Integer;
1043 Result := MYSQL_API.mysql_stmt_execute (PMYSQL_STMT(Handle));
1046 function TZMySQLBaseDriver.FetchBoundResults(Handle: PZMySqlPrepStmt): Integer;
1048 Result := MYSQL_API.mysql_stmt_fetch (PMYSQL_STMT(Handle));
1051 function TZMySQLBaseDriver.GetPreparedFieldCount(Handle: PZMySqlPrepStmt): Integer;
1053 Result := MYSQL_API.mysql_stmt_field_count(PMYSQL_STMT(Handle));
1056 function TZMySQLBaseDriver.FreePreparedResult(Handle: PZMySqlPrepStmt): Byte;
1058 Result := MYSQL_API.mysql_stmt_free_result(PMYSQL_STMT(Handle));
1061 function TZMySQLBaseDriver.InitializePrepStmt (Handle: PZMySQLConnect): PZMySqlPrepStmt;
1063 Result := MYSQL_API.mysql_stmt_init(PMYSQL(Handle));
1066 function TZMySQLBaseDriver.GetPreparedInsertID(Handle: PZMySqlPrepStmt): Int64;
1068 Result := MYSQL_API.mysql_stmt_insert_id (PMYSQL_STMT(Handle));
1071 function TZMySQLBaseDriver.GetPreparedNextResult(Handle: PZMySqlPrepStmt): Integer;
1073 if (@MYSQL_API.mysql_stmt_next_result = nil) then
1074 Result := -1 // Successful and there are no more results
1076 Result := MYSQL_API.mysql_stmt_next_result (PMYSQL_STMT(Handle));
1079 function TZMySQLBaseDriver.GetPreparedNumRows(Handle: PZMySqlPrepStmt): Int64;
1081 if (Handle = nil) then
1084 Result := MYSQL_API.mysql_stmt_num_rows (PMYSQL_STMT(Handle));
1087 function TZMySQLBaseDriver.GetPreparedBindMarkers (Handle: PZMySqlPrepStmt): Cardinal;
1089 Result := MYSQL_API.mysql_stmt_param_count (PMYSQL_STMT(Handle));
1092 function TZMySQLBaseDriver.GetStmtParamMetadata(PrepStmtHandle: PZMySqlPrepStmt): PZMySQLResult;
1094 Result := MYSQL_API.mysql_stmt_param_metadata(PMYSQL_STMT(PrepStmtHandle));
1097 function TZMySQLBaseDriver.PrepareStmt(PrepStmtHandle: PZMySqlPrepStmt; const Query: PAnsiChar; Length: Integer): Integer;
1099 Result := MYSQL_API.mysql_stmt_prepare(PMYSQL_STMT(PrepStmtHandle), Query, Length);
1102 function TZMySQLBaseDriver.stmt_reset(PrepStmtHandle: PZMySqlPrepStmt): Byte;
1104 Result := MYSQL_API.mysql_stmt_reset(PrepStmtHandle);
1107 function TZMySQLBaseDriver.GetPreparedMetaData (Handle: PZMySqlPrepStmt): PZMySQLResult;
1109 Result := MYSQL_API.mysql_stmt_result_metadata (PMYSQL_STMT(Handle));
1112 function TZMySQLBaseDriver.SeekPreparedRow(Handle: PZMySqlPrepStmt; Row: PZMySQLRowOffset): PZMySQLRowOffset;
1114 Result := MYSQL_API.mysql_stmt_row_seek (PMYSQL_STMT(Handle), Row);
1117 function TZMySQLBaseDriver.SendPreparedLongData(Handle: PZMySqlPrepStmt;
1118 parameter_number: Cardinal; const data: PAnsiChar; length: Cardinal): Byte;
1120 Result := MYSQL_API.mysql_stmt_send_long_data(PMYSQL_STMT(Handle), parameter_number, data, length);
1123 function TZMySQLBaseDriver.GetPreparedSQLState(Handle: PZMySqlPrepStmt): PAnsiChar;
1125 Result := MYSQL_API.mysql_stmt_sqlstate (PMYSQL_STMT(Handle));
1128 function TZMySQLBaseDriver.StorePreparedResult (Handle: PZMySqlPrepStmt): Integer;
1130 Result := MYSQL_API.mysql_stmt_store_result (PMYSQL_STMT(Handle));
1133 procedure TZMySQLBaseDriver.GetCharacterSetInfo(Handle: PZMySQLConnect; CharSetInfo: PMY_CHARSET_INFO);
1135 MYSQL_API.mysql_get_character_set_info(Handle, CharSetInfo);
1138 function TZMySQLBaseDriver.GetBindOffsets: MYSQL_BINDOFFSETS;
1140 DriverVersion : Integer;
1142 DriverVersion:=GetClientVersion;
1143 case DriverVersion of
1144 40100..40199 : begin
1145 result.buffer_type := NativeUint(@(PMYSQL_BIND41(nil).buffer_type));
1146 result.buffer_length := NativeUint(@(PMYSQL_BIND41(nil).buffer_length));
1147 result.is_unsigned := NativeUint(@(PMYSQL_BIND41(nil).is_unsigned));
1148 result.buffer := NativeUint(@(PMYSQL_BIND41(nil).buffer));
1149 result.length := NativeUint(@(PMYSQL_BIND41(nil).length));
1150 result.is_null := NativeUint(@(PMYSQL_BIND41(nil).is_null));
1151 result.size := Sizeof(MYSQL_BIND41);
1153 50000..50099 : begin
1154 result.buffer_type := NativeUint(@(PMYSQL_BIND50(nil).buffer_type));
1155 result.buffer_length := NativeUint(@(PMYSQL_BIND50(nil).buffer_length));
1156 result.is_unsigned := NativeUint(@(PMYSQL_BIND50(nil).is_unsigned));
1157 result.buffer := NativeUint(@(PMYSQL_BIND50(nil).buffer));
1158 result.length := NativeUint(@(PMYSQL_BIND50(nil).length));
1159 result.is_null := NativeUint(@(PMYSQL_BIND50(nil).is_null));
1160 result.size := Sizeof(MYSQL_BIND50);
1162 50100..59999 : begin
1163 result.buffer_type := NativeUint(@(PMYSQL_BIND51(nil).buffer_type));
1164 result.buffer_length := NativeUint(@(PMYSQL_BIND51(nil).buffer_length));
1165 result.is_unsigned := NativeUint(@(PMYSQL_BIND51(nil).is_unsigned));
1166 result.buffer := NativeUint(@(PMYSQL_BIND51(nil).buffer));
1167 result.length := NativeUint(@(PMYSQL_BIND51(nil).length));
1168 result.is_null := NativeUint(@(PMYSQL_BIND51(nil).is_null));
1169 result.size := Sizeof(MYSQL_BIND51);
1171 60000..60099 : begin
1172 result.buffer_type := NativeUint(@(PMYSQL_BIND60(nil).buffer_type));
1173 result.buffer_length := NativeUint(@(PMYSQL_BIND60(nil).buffer_length));
1174 result.is_unsigned := NativeUint(@(PMYSQL_BIND60(nil).is_unsigned));
1175 result.buffer := NativeUint(@(PMYSQL_BIND60(nil).buffer));
1176 result.length := NativeUint(@(PMYSQL_BIND60(nil).length));
1177 result.is_null := NativeUint(@(PMYSQL_BIND60(nil).is_null));
1178 result.size := Sizeof(MYSQL_BIND60);
1181 if FIsMariaDBDriver and (DriverVersion >= 100000) then //MariaDB 10
1183 result.buffer_type := {%H-}NativeUint(@(PMYSQL_BIND60(nil).buffer_type));
1184 result.buffer_length := {%H-}NativeUint(@(PMYSQL_BIND60(nil).buffer_length));
1185 result.is_unsigned := {%H-}NativeUint(@(PMYSQL_BIND60(nil).is_unsigned));
1186 result.buffer := {%H-}NativeUint(@(PMYSQL_BIND60(nil).buffer));
1187 result.length := {%H-}NativeUint(@(PMYSQL_BIND60(nil).length));
1188 result.is_null := {%H-}NativeUint(@(PMYSQL_BIND60(nil).is_null));
1189 result.size := Sizeof(MYSQL_BIND60);
1192 result.buffer_type:=0;
1196 function TZMySQLBaseDriver.StoreResult(
1197 Handle: PZMySQLConnect): PZMySQLResult;
1199 Result := MYSQL_API.mysql_store_result(Handle);
1202 function TZMySQLBaseDriver.UseResult(Handle: PZMySQLConnect): PZMySQLResult;
1204 Result := MYSQL_API.mysql_use_result(Handle);
1207 function TZMySQLBaseDriver.GetLastError(Handle: PZMySQLConnect): PAnsiChar;
1209 Result := MYSQL_API.mysql_error(Handle);
1212 function TZMySQLBaseDriver.GetFieldType(Field: PZMySQLField): TMysqlFieldTypes;
1214 Result := PMYSQL_FIELD(Field)^._type;
1217 function TZMySQLBaseDriver.GetFieldFlags(Field: PZMySQLField): Integer;
1219 Result := PMYSQL_FIELD(Field)^.flags;
1222 function TZMySQLBaseDriver.GetRowCount(Res: PZMySQLResult): Int64;
1224 Result := MYSQL_API.mysql_num_rows(Res);
1227 function TZMySQLBaseDriver.ResultSetExists(Handle: PZMySQLConnect): Boolean;
1229 result := MYSQL_API.mysql_field_count(Handle)<>0;
1230 // True If statement should return a resultset
1233 function TZMySQLBaseDriver.GetFieldCount(Res: PZMySQLResult): Integer;
1235 Result := MYSQL_API.mysql_num_fields(Res);
1238 function TZMySQLBaseDriver.GetFieldDecimals(Field: PZMySQLField): Integer;
1240 Result := PMYSQL_FIELD(Field)^.decimals;
1243 function TZMySQLBaseDriver.GetFieldCharsetNr(Field: PZMySQLField): UInt;
1245 Result := PMYSQL_FIELD(Field)^.charsetnr;
1248 function TZMySQLBaseDriver.GetFieldLength(Field: PZMySQLField): ULong;
1250 Result := PMYSQL_FIELD(Field)^.length;
1253 function TZMySQLBaseDriver.GetFieldMaxLength(Field: PZMySQLField): Integer;
1255 Result := PMYSQL_FIELD(Field)^.max_length;
1258 function TZMySQLBaseDriver.GetFieldName(Field: PZMySQLField): PAnsiChar;
1260 Result := PMYSQL_FIELD(Field)^.name;
1263 function TZMySQLBaseDriver.GetFieldTable(Field: PZMySQLField): PAnsiChar;
1265 Result := PMYSQL_FIELD(Field)^.table;
1268 function TZMySQLBaseDriver.GetFieldOrigTable(Field: PZMySQLField): PAnsiChar;
1270 Result := PMYSQL_FIELD(Field)^.org_table;
1273 function TZMySQLBaseDriver.GetFieldOrigName(Field: PZMySQLField): PAnsiChar;
1275 Result := PMYSQL_FIELD(Field)^.org_name;
1278 function TZMySQLBaseDriver.GetFieldData(Row: PZMySQLRow;
1279 Offset: Cardinal): PAnsiChar;
1281 Result := PMYSQL_ROW(ROW)[Offset];
1284 function TZMySQLBaseDriver.GetLastErrorCode(Handle: PZMySQLConnect): Integer;
1286 Result := MYSQL_API.mysql_errno(PMYSQL(Handle));
1289 function TZMySQLBaseDriver.GetClientVersion: Integer;
1291 Result := MYSQL_API.mysql_get_client_version;
1294 function TZMySQLBaseDriver.GetServerVersion(
1295 Handle: PZMySQLConnect): Integer;
1297 Result := MYSQL_API.mysql_get_server_version(Handle);
1300 procedure TZMySQLBaseDriver.SetDriverOptions(Options: TStrings);
1302 PreferedLibrary: String;
1304 PreferedLibrary := Options.Values['Library'];
1305 if PreferedLibrary <> '' then
1306 Loader.AddLocation(PreferedLibrary);
1307 if IsEmbeddedDriver then
1308 BuildServerArguments(Options);
1311 { TZMySQL41PlainDriver }
1313 function TZMySQL41PlainDriver.Clone: IZPlainDriver;
1315 Result := TZMySQL41PlainDriver.Create(FTokenizer);
1318 constructor TZMySQL41PlainDriver.Create(Tokenizer: IZTokenizer);
1320 inherited Create(Tokenizer);
1322 FLoader.AddLocation(WINDOWS_DLL41_LOCATION);
1324 FLoader.AddLocation(LINUX_DLL41_LOCATION);
1328 function TZMySQL41PlainDriver.GetProtocol: string;
1330 Result := 'mysql-4.1';
1333 function TZMySQL41PlainDriver.GetDescription: string;
1335 Result := 'Native Plain Driver for MySQL 4.1+';
1338 { TZMySQLD41PlainDriver }
1340 function TZMySQLD41PlainDriver.Clone: IZPlainDriver;
1342 Result := TZMySQLD41PlainDriver.Create(FTokenizer);
1345 constructor TZMySQLD41PlainDriver.Create(Tokenizer: IZTokenizer);
1347 inherited Create(Tokenizer);
1348 // only include embedded library
1349 FLoader.ClearLocations;
1350 {$IFNDEF MYSQL_STRICT_DLL_LOADING}
1352 FLoader.AddLocation(WINDOWS_DLL_LOCATION_EMBEDDED);
1354 FLoader.AddLocation(LINUX_DLL_LOCATION_EMBEDDED);
1358 FLoader.AddLocation(WINDOWS_DLL41_LOCATION_EMBEDDED);
1360 FLoader.AddLocation(LINUX_DLL41_LOCATION_EMBEDDED);
1362 IsEmbeddedDriver := True;
1365 function TZMySQLD41PlainDriver.GetProtocol: string;
1367 Result := 'mysqld-4.1';
1370 function TZMySQLD41PlainDriver.GetDescription: string;
1372 Result := 'Native Plain Driver for Embedded MySQL 4.1+';
1375 { TZMySQL5PlainDriver }
1377 function TZMySQL5PlainDriver.Clone: IZPlainDriver;
1379 Result := TZMySQL5PlainDriver.Create(FTokenizer);
1382 procedure TZMySQL5PlainDriver.LoadApi;
1388 @MYSQL_API.mysql_get_character_set_info := GetAddress('mysql_get_character_set_info');
1389 @MYSQL_API.mysql_stmt_next_result := GetAddress('mysql_stmt_next_result');
1393 procedure TZMySQL5PlainDriver.LoadCodePages;
1395 inherited LoadCodePages;
1398 AddCodePage('utf8mb4', 37, ceUTF8, zCP_UTF8, '', 4); {UTF-8 Unicode}
1399 AddCodePage('utf16', 38, ceUTF16, zCP_UTF16, 'utf8', 4); {UTF-16 Unicode}
1400 AddCodePage('utf32', 39, ceUTF16, zCP_utf32, 'utf8', 4); {UTF-32 Unicode} //Egonhugeist improved
1403 constructor TZMySQL5PlainDriver.Create(Tokenizer: IZTokenizer);
1405 inherited Create(Tokenizer);
1407 {$IFNDEF MYSQL_STRICT_DLL_LOADING}
1408 FLoader.AddLocation(MARIADB_LOCATION);
1410 FLoader.AddLocation(WINDOWS_DLL50_LOCATION);
1411 FLoader.AddLocation(WINDOWS_DLL51_LOCATION);
1412 FLoader.AddLocation(WINDOWS_DLL55_LOCATION);
1414 {$IFNDEF MYSQL_STRICT_DLL_LOADING}
1415 FLoader.AddLocation(MARIADB_LOCATION);
1417 FLoader.AddLocation(LINUX_DLL50_LOCATION);
1418 FLoader.AddLocation(LINUX_DLL51_LOCATION);
1419 FLoader.AddLocation(LINUX_DLL55_LOCATION);
1423 function TZMySQL5PlainDriver.GetProtocol: string;
1425 Result := 'mysql-5';
1428 function TZMySQL5PlainDriver.GetDescription: string;
1430 Result := 'Native Plain Driver for MySQL 5.0+';
1433 { TZMySQLD5PlainDriver }
1435 function TZMySQLD5PlainDriver.Clone: IZPlainDriver;
1437 Result := TZMySQLD5PlainDriver.Create(FTokenizer);
1440 constructor TZMySQLD5PlainDriver.Create(Tokenizer: IZTokenizer);
1442 inherited Create(Tokenizer);
1443 // only include embedded library
1444 FLoader.ClearLocations;
1445 {$IFNDEF MYSQL_STRICT_DLL_LOADING}
1447 FLoader.AddLocation(WINDOWS_DLL_LOCATION_EMBEDDED);
1449 FLoader.AddLocation(LINUX_DLL_LOCATION_EMBEDDED);
1453 FLoader.AddLocation(WINDOWS_DLL50_LOCATION_EMBEDDED);
1454 FLoader.AddLocation(WINDOWS_DLL51_LOCATION_EMBEDDED);
1455 FLoader.AddLocation(WINDOWS_DLL55_LOCATION_EMBEDDED);
1457 FLoader.AddLocation(LINUX_DLL50_LOCATION_EMBEDDED);
1458 FLoader.AddLocation(LINUX_DLL51_LOCATION_EMBEDDED);
1459 FLoader.AddLocation(LINUX_DLL55_LOCATION_EMBEDDED);
1461 IsEmbeddedDriver := True;
1464 function TZMySQLD5PlainDriver.GetProtocol: string;
1466 Result := 'mysqld-5';
1469 function TZMySQLD5PlainDriver.GetDescription: string;
1471 Result := 'Native Plain Driver for Embedded MySQL 5+';
1474 { TZMariaDB5PlainDriver }
1475 function TZMariaDB5PlainDriver.Clone: IZPlainDriver;
1477 Result := TZMariaDB5PlainDriver.Create(FTokenizer);
1480 constructor TZMariaDB5PlainDriver.Create(Tokenizer: IZTokenizer);
1482 inherited Create(Tokenizer);
1483 FLoader.ClearLocations;
1484 FLoader.AddLocation(MARIADB_LOCATION);
1487 function TZMariaDB5PlainDriver.GetProtocol: string;
1489 Result := 'MariaDB-5';
1492 function TZMariaDB5PlainDriver.GetDescription: string;
1494 Result := 'Native Plain Driver for MariaDB-5.x';