zeoslib  UNKNOWN
 All Files
ZPlainMySqlDriver.pas
Go to the documentation of this file.
1 {*********************************************************}
2 { }
3 { Zeos Database Objects }
4 { Native Plain Drivers for MySQL }
5 { }
6 { Originally written by Sergey Seroukhov }
7 { }
8 { Thanks to : }
9 { Pascal Data Objects Library }
10 { }
11 { Copyright (c) 2006 John Marino, www.synsport.com }
12 { }
13 {*********************************************************}
14 
15 {@********************************************************}
16 { Copyright (c) 1999-2012 Zeos Development Group }
17 { }
18 { License Agreement: }
19 { }
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. }
25 { }
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. }
44 { }
45 { }
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) }
50 { }
51 { http://www.sourceforge.net/projects/zeoslib. }
52 { }
53 { }
54 { Zeos Development Group. }
55 {********************************************************@}
56 
57 unit ZPlainMySqlDriver;
58 
59 interface
60 
61 {$I ZPlain.inc}
62 
63 uses Classes, {$IFDEF MSEgui}mclasses,{$ENDIF}
64  ZPlainDriver, ZCompatibility, ZPlainMySqlConstants, ZTokenizer;
65 
66 const
67  MARIADB_LOCATION = 'libmariadb'+ SharedSuffix;
68 {$IFNDEF UNIX}
69  {$IFNDEF MYSQL_STRICT_DLL_LOADING}
70  WINDOWS_DLL_LOCATION = 'libmysql.dll';
71  WINDOWS_DLL_LOCATION_EMBEDDED = 'libmysqld.dll';
72  {$ENDIF}
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';
81 {$ELSE}
82  {$IFNDEF MYSQL_STRICT_DLL_LOADING}
83  LINUX_DLL_LOCATION = 'libmysqlclient'+SharedSuffix;
84  LINUX_DLL_LOCATION_EMBEDDED = 'libmysqld'+SharedSuffix;
85  {$ENDIF}
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';
94 {$ENDIF}
95 
96 type
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);
106 
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;
117  // eof
118  function GetLastErrorCode(Handle: PZMySQLConnect): Integer;
119  function GetLastError(Handle: PZMySQLConnect): PAnsiChar;
120  function FetchField(Res: PZMySQLResult): PZMySQLField;
121  // fetch_field_direct
122  // fetch_fields
123  function FetchLengths(Res: PZMySQLResult): PULong;
124  function FetchRow(Res: PZMySQLResult): PZMySQLRow;
125  function SeekField(Res: PZMySQLResult; Offset: Cardinal): Cardinal;
126  // field_tell
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;
132  // info
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;
141  // num_fields
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;
150  // row_tell
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;
157 
158  // thread_init
159  // thread_end
160  // thread_safe
161 
162  // server_init
163  // server_end
164 
165  // change_user
166  // field_count
167  // function GetClientVersion: AnsiString;
168 
169  function Shutdown(Handle: PZMySQLConnect; shutdown_level: TMysqlShutdownLevel = ZPlainMySqlConstants.SHUTDOWN_DEFAULT): Integer; // 2 versions!!
170 
171  function SetAutocommit (Handle: PZMySQLConnect; mode: Boolean): Boolean;
172  function Commit (Handle: PZMySQLConnect): Boolean;
173  //function GetServerVersion (Handle: PZMySQLConnect): AnsiString;
174  // hex_string
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
180  // set_server_option
181  function GetSQLState (Handle: PZMySQLConnect): AnsiString;
182  // warning_count
183 
184  function GetPreparedAffectedRows (Handle: PZMySqlPrepStmt): Int64;
185  // stmt_attr_get
186  function StmtAttrSet(stmt: PZMySqlPrepStmt; option: TMysqlStmtAttrType;
187  arg: Pointer): Byte;
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;
196  // stmt_fetch_column
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
204 
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;
210  // stmt_row_tell
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;
214 
215  procedure GetCharacterSetInfo(Handle: PZMySQLConnect; CharSetInfo: PMY_CHARSET_INFO);// get_character_set_info since 5.0.10
216 
217  {non API functions}
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
233  end;
234 
235  {** Implements a base driver for MySQL}
236 
237  { TZMySQLBaseDriver }
238 
239  TZMySQLBaseDriver = class (TZAbstractPlainDriver, IZPlainDriver, IZMySQLPlainDriver)
240  private
241  FIsMariaDBDriver: Boolean;
242  protected
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);
251  public
252  constructor Create(Tokenizer: IZTokenizer);
253  destructor Destroy; override;
254 
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);
263 
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);
270 
271  function ExecQuery(Handle: PZMySQLConnect; const Query: PAnsiChar): Integer; overload;
272  function ExecRealQuery(Handle: PZMySQLConnect; const Query: PAnsiChar;
273  Length: Integer): Integer;
274 
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;
282 
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;
290 
291  function StmtAttrSet(stmt: PZMySqlPrepStmt; option: TMysqlStmtAttrType;
292  arg: Pointer): Byte;
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);
318 
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;
323 
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;
346 
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
354 
355  function FetchRow(Res: PZMySQLResult): PZMySQLRow;
356  function FetchLengths(Res: PZMySQLResult): PULong;
357  function FetchField(Res: PZMySQLResult): PZMySQLField;
358 
359  procedure SeekData(Res: PZMySQLResult; Offset: Cardinal);
360  function SeekRow(Res: PZMySQLResult; Row: PZMySQLRowOffset):
361  PZMySQLRowOffset;
362  function SeekField(Res: PZMySQLResult; Offset: Cardinal): Cardinal;
363 
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
379  end;
380 
381  {** Implements a driver for MySQL 4.1 }
382 
383  { TZNewMySQL41PlainDriver }
384 
385  TZMySQL41PlainDriver = class (TZMysqlBaseDriver)
386  protected
387  function Clone: IZPlainDriver; override;
388  public
389  constructor Create(Tokenizer: IZTokenizer);
390  function GetProtocol: string; override;
391  function GetDescription: string; override;
392  end;
393 
394  {** Implements a driver for MySQL 4.1 }
395 
396  { TZNewMySQLD41PlainDriver }
397 
398  TZMySQLD41PlainDriver = class (TZMySQL41PlainDriver)
399  protected
400  function Clone: IZPlainDriver; override;
401  public
402  constructor Create(Tokenizer: IZTokenizer);
403  function GetProtocol: string; override;
404  function GetDescription: string; override;
405  end;
406 
407  { TZNewMySQL5PlainDriver }
408 
409  TZMySQL5PlainDriver = class (TZMysqlBaseDriver)
410  protected
411  function Clone: IZPlainDriver; override;
412  protected
413  procedure LoadApi; override;
414  procedure LoadCodePages; override;
415  public
416  constructor Create(Tokenizer: IZTokenizer);
417  function GetProtocol: string; override;
418  function GetDescription: string; override;
419  end;
420 
421  { TZNewMySQLD5PlainDriver }
422 
423  TZMySQLD5PlainDriver = class (TZMySQL5PlainDriver)
424  protected
425  function Clone: IZPlainDriver; override;
426  public
427  constructor Create(Tokenizer: IZTokenizer);
428  function GetProtocol: string; override;
429  function GetDescription: string; override;
430  end;
431 
432  { TZMariaDB5PlainDriver }
433 
434  TZMariaDB5PlainDriver = class (TZMySQL5PlainDriver)
435  protected
436  function Clone: IZPlainDriver; override;
437  public
438  constructor Create(Tokenizer: IZTokenizer);
439  function GetProtocol: string; override;
440  function GetDescription: string; override;
441  end;
442 
443 implementation
444 
445 uses SysUtils, ZPlainLoader, ZEncoding
446  {$IFDEF WITH_UNITANSISTRINGS}, AnsiStrings{$ENDIF};
447 
448 { TZMySQLPlainBaseDriver }
449 function TZMySQLBaseDriver.GetUnicodeCodePageName: String;
450 begin
451  Result := 'utf8';
452 end;
453 
454 procedure TZMySQLBaseDriver.LoadCodePages;
455 begin
456  {MySQL 3.23-4.1}
457  { MultiByte }
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}
468  { SingleChar }
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}
495 end;
496 
497 procedure TZMySQLBaseDriver.LoadApi;
498 begin
499 { ************** Load adresses of API Functions ************* }
500  with Loader do
501  begin
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');
554 
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');
559 
560  @MYSQL_API.mysql_server_init := GetAddress('mysql_server_init');
561  @MYSQL_API.mysql_server_end := GetAddress('mysql_server_end');
562 
563  @MYSQL_API.mysql_change_user := GetAddress('mysql_change_user');
564  @MYSQL_API.mysql_field_count := GetAddress('mysql_field_count');
565 
566  @MYSQL_API.mysql_get_client_version := GetAddress('mysql_get_client_version');
567 
568  @MYSQL_API.mysql_send_query := GetAddress('mysql_send_query');
569  @MYSQL_API.mysql_read_query_result := GetAddress('mysql_read_query_result');
570 
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');
610  end;
611 end;
612 
613 procedure TZMySQLBaseDriver.BuildServerArguments(Options: TStrings);
614 var
615  TmpList: TStringList;
616  i: Integer;
617 begin
618  TmpList := TStringList.Create;
619  try
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);
629 
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
635  {$IFDEF UNICODE}
636  ServerArgs[i] := {$IFDEF WITH_STRNEW_DEPRECATED}AnsiStrings.{$ENDIF}StrNew(PAnsiChar(UTF8String(TmpList[i])));
637  {$ELSE}
638  ServerArgs[i] := StrNew(PAnsiChar(TmpList[i]));
639  {$ENDIF}
640  finally
641  TmpList.Free;
642  end;
643 end;
644 
645 constructor TZMySQLBaseDriver.Create(Tokenizer: IZTokenizer);
646 begin
647  inherited create;
648  FLoader := TZNativeLibraryLoader.Create([]);
649  FTokenizer := nil;
650  FTokenizer := Tokenizer;
651 {$IFNDEF MYSQL_STRICT_DLL_LOADING}
652  {$IFNDEF UNIX}
653  FLoader.AddLocation(WINDOWS_DLL_LOCATION);
654  {$ELSE}
655  FLoader.AddLocation(LINUX_DLL_LOCATION);
656  {$ENDIF}
657 {$ENDIF}
658  ServerArgsLen := 0;
659  SetLength(ServerArgs, ServerArgsLen);
660  IsEmbeddedDriver := False;
661  LoadCodePages;
662 end;
663 
664 destructor TZMySQLBaseDriver.Destroy;
665 var
666  i : integer;
667 begin
668  for i := 0 to ServerArgsLen - 1 do
669  {$IFDEF WITH_STRDISPOSE_DEPRECATED}AnsiStrings.{$ENDIF}StrDispose(ServerArgs[i]);
670 
671  if (FLoader.Loaded) then
672  if (@ MYSQL_API.mysql_library_end <> nil) then
673  MYSQL_API.mysql_library_end //since 5.0.3
674  else
675  if (@ MYSQL_API.mysql_server_end <> nil) then
676  MYSQL_API.mysql_server_end; //deprected since 5.0.3
677  inherited Destroy;
678 end;
679 
680 function TZMySQLBaseDriver.IsMariaDBDriver: Boolean;
681 begin
682  Result := FIsMariaDBDriver;
683 end;
684 
685 procedure TZMySQLBaseDriver.Close(Handle: PZMySQLConnect);
686 begin
687  MYSQL_API.mysql_close(Handle);
688 end;
689 
690 function TZMySQLBaseDriver.Connect(Handle: PZMySQLConnect; const Host,
691  User, Password: PAnsiChar): PZMySQLConnect;
692 begin
693  Result := MYSQL_API.mysql_connect(Handle, Host, User, Password);
694 end;
695 
696 function TZMySQLBaseDriver.SslSet(Handle: PZMySQLConnect;
697  const Key, Cert, Ca, Capath, Cipher: PAnsiChar): Integer;
698 begin
699  Result := MYSQL_API.mysql_ssl_set(Handle, Key, Cert, Ca, Capath, Cipher);
700 end;
701 
702 function TZMySQLBaseDriver.CreateDatabase(Handle: PZMySQLConnect;
703  const Database: PAnsiChar): Integer;
704 begin
705  Result := MYSQL_API.mysql_create_db(Handle, Database);
706 end;
707 
708 procedure TZMySQLBaseDriver.Debug(Debug: PAnsiChar);
709 begin
710  MYSQL_API.mysql_debug(Debug);
711 end;
712 
713 function TZMySQLBaseDriver.DropDatabase(Handle: PZMySQLConnect;
714  const Database: PAnsiChar): Integer;
715 begin
716  Result := MYSQL_API.mysql_drop_db(Handle, Database);
717 end;
718 
719 function TZMySQLBaseDriver.DumpDebugInfo(Handle: PZMySQLConnect): Integer;
720 begin
721  Result := MYSQL_API.mysql_dump_debug_info(Handle);
722 end;
723 
724 function TZMySQLBaseDriver.ExecQuery(Handle: PZMySQLConnect;
725  const Query: PAnsiChar): Integer;
726 begin
727  Result := MYSQL_API.mysql_query(Handle, Query);
728 end;
729 
730 function TZMySQLBaseDriver.ExecRealQuery(Handle: PZMySQLConnect;
731  const Query: PAnsiChar; Length: Integer): Integer;
732 begin
733  Result := MYSQL_API.mysql_real_query(Handle, Query, Length);
734 end;
735 
736 function TZMySQLBaseDriver.FetchField(Res: PZMySQLResult): PZMySQLField;
737 begin
738  Result := MYSQL_API.mysql_fetch_field(Res);
739 end;
740 
741 function TZMySQLBaseDriver.FetchLengths(Res: PZMySQLResult): PULong;
742 begin
743  Result := MYSQL_API.mysql_fetch_lengths(Res);
744 end;
745 
746 function TZMySQLBaseDriver.FetchRow(Res: PZMySQLResult): PZMySQLRow;
747 begin
748  Result := MYSQL_API.mysql_fetch_row(Res);
749 end;
750 
751 procedure TZMySQLBaseDriver.FreeResult(Res: PZMySQLResult);
752 begin
753  MYSQL_API.mysql_free_result(Res);
754 end;
755 
756 function TZMySQLBaseDriver.GetAffectedRows(Handle: PZMySQLConnect): Int64;
757 begin
758  Result := MYSQL_API.mysql_affected_rows(Handle);
759 end;
760 
761 {**
762  EgonHugeist: Get CharacterSet of current Connection
763  Returns the default character set name for the current connection.
764 }
765 function TZMySQLBaseDriver.GetConnectionCharacterSet(Handle: PMYSQL): PAnsiChar;// char_set_name
766 begin
767  if Assigned(MYSQL_API.mysql_character_set_name) then
768  Result := MYSQL_API.mysql_character_set_name(Handle)
769  else
770  Result := '';
771 end;
772 
773 {**
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()
780 }
781 function TZMySQLBaseDriver.SetConnectionCharacterSet(Handle: PMYSQL;
782  const csname: PAnsiChar): Integer; // set_character_set Returns 0 if valid
783 begin
784  Result := MYSQL_API.mysql_set_character_set(Handle, csName);
785 end;
786 
787 function TZMySQLBaseDriver.GetClientInfo: PAnsiChar;
788 begin
789  Result := MYSQL_API.mysql_get_client_info;
790 end;
791 
792 function TZMySQLBaseDriver.EscapeString(Handle: Pointer; const Value: RawByteString;
793  ConSettings: PZConSettings; WasEncoded: Boolean = False): RawByteString;
794 var
795  Len, outlength: integer;
796  Outbuffer: RawByteString;
797  TempValue: RawByteString;
798 begin
799  {$IFDEF UNICODE}
800  TempValue := Value;
801  {$ELSE}
802  if WasEncoded then
803  TempValue := Value
804  else
805  TempValue := ZPlainString(Value, ConSettings); //check encoding too
806  {$ENDIF}
807  Len := Length(TempValue);
808  Setlength(Outbuffer,Len*2+1);
809  if Handle = nil then
810  OutLength := MYSQL_API.mysql_escape_string(PAnsiChar(OutBuffer), PAnsiChar(TempValue), Len)
811  else
812  OutLength := MYSQL_API.mysql_real_escape_string(Handle, PAnsiChar(OutBuffer), PAnsiChar(TempValue), Len);
813  Setlength(Outbuffer,OutLength);
814  Result := #39+Outbuffer+#39;
815 end;
816 
817 function TZMySQLBaseDriver.GetHostInfo(Handle: PZMySQLConnect): PAnsiChar;
818 begin
819  Result := MYSQL_API.mysql_get_host_info(Handle);
820 end;
821 
822 function TZMySQLBaseDriver.GetListDatabases(Handle: PZMySQLConnect;
823  Wild: PAnsiChar): PZMySQLResult;
824 begin
825  Result := MYSQL_API.mysql_list_dbs(Handle, Wild);
826 end;
827 
828 function TZMySQLBaseDriver.GetListFields(Handle: PZMySQLConnect;
829  const Table, Wild: PAnsiChar): PZMySQLResult;
830 begin
831  Result := MYSQL_API.mysql_list_fields(Handle, Table, Wild);
832 end;
833 
834 function TZMySQLBaseDriver.GetListProcesses(
835  Handle: PZMySQLConnect): PZMySQLResult;
836 begin
837  Result := MYSQL_API.mysql_list_processes(Handle);
838 end;
839 
840 function TZMySQLBaseDriver.GetListTables(Handle: PZMySQLConnect;
841  const Wild: PAnsiChar): PZMySQLResult;
842 begin
843  Result := MYSQL_API.mysql_list_tables(Handle, Wild);
844 end;
845 
846 function TZMySQLBaseDriver.GetNumRows(Res: PZMySQLResult): Int64;
847 begin
848  if (Res = nil) then
849  Result := 0
850  else
851  Result := MYSQL_API.mysql_num_rows (Res);
852 end;
853 
854 function TZMySQLBaseDriver.GetProtoInfo(Handle: PZMySQLConnect): Cardinal;
855 begin
856  Result := MYSQL_API.mysql_get_proto_info(Handle);
857 end;
858 
859 function TZMySQLBaseDriver.GetServerInfo(Handle: PZMySQLConnect): PAnsiChar;
860 begin
861  Result := MYSQL_API.mysql_get_server_info(Handle);
862 end;
863 
864 function TZMySQLBaseDriver.GetStatInfo(Handle: PZMySQLConnect): PAnsiChar;
865 begin
866  Result := MYSQL_API.mysql_stat(Handle);
867 end;
868 
869 function TZMySQLBaseDriver.GetThreadId(Handle: PZMySQLConnect): Cardinal;
870 begin
871  Result := MYSQL_API.mysql_thread_id(Handle);
872 end;
873 
874 function TZMySQLBaseDriver.Init(const Handle: PZMySQLConnect): PZMySQLConnect;
875 var
876  ClientInfo: PAnsiChar;
877  L: Integer;
878 begin
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);
885 end;
886 
887 function TZMySQLBaseDriver.GetLastInsertID(Handle: PZMySQLConnect): Int64;
888 begin
889  Result := MYSQL_API.mysql_insert_id(PMYSQL(Handle));
890 end;
891 
892 procedure TZMySQLBaseDriver.Despose(var Handle: PZMySQLConnect);
893 begin
894  Handle := nil;
895 end;
896 
897 function TZMySQLBaseDriver.Kill(Handle: PZMySQLConnect; Pid: LongInt): Integer;
898 begin
899  Result := MYSQL_API.mysql_kill(Handle, Pid);
900 end;
901 
902 function TZMySQLBaseDriver.Ping(Handle: PZMySQLConnect): Integer;
903 begin
904  Result := MYSQL_API.mysql_ping(Handle);
905 end;
906 
907 function TZMySQLBaseDriver.RealConnect(Handle: PZMySQLConnect;
908  const Host, User, Password, Db: PAnsiChar; Port: Cardinal; UnixSocket: PAnsiChar;
909  ClientFlag: Cardinal): PZMySQLConnect;
910 begin
911  Result := MYSQL_API.mysql_real_connect(Handle, Host, User, Password, Db,
912  Port, UnixSocket, ClientFlag);
913 end;
914 
915 {function TZMySQLBaseDriver.GetRealEscapeString(Handle: PZMySQLConnect; StrTo, StrFrom: PAnsiChar;
916  Length: Cardinal): Cardinal;
917 begin
918  Result := MYSQL_API.mysql_real_escape_string(Handle, StrTo, StrFrom, Length);
919 end;}
920 
921 function TZMySQLBaseDriver.Refresh(Handle: PZMySQLConnect;
922  Options: Cardinal): Integer;
923 begin
924  Result := MYSQL_API.mysql_refresh(Handle, Options);
925 end;
926 
927 procedure TZMySQLBaseDriver.SeekData(Res: PZMySQLResult;
928  Offset: Cardinal);
929 begin
930  MYSQL_API.mysql_data_seek(Res, Offset);
931 end;
932 
933 function TZMySQLBaseDriver.SeekField(Res: PZMySQLResult;
934  Offset: Cardinal): Cardinal;
935 begin
936  Result := MYSQL_API.mysql_field_seek(Res, Offset);
937 end;
938 
939 function TZMySQLBaseDriver.SeekRow(Res: PZMySQLResult;
940  Row: PZMySQLRowOffset): PZMySQLRowOffset;
941 begin
942  Result := MYSQL_API.mysql_row_seek(Res, Row);
943 end;
944 
945 function TZMySQLBaseDriver.SelectDatabase(Handle: PZMySQLConnect;
946  const Database: PAnsiChar): Integer;
947 begin
948  Result := MYSQL_API.mysql_select_db(Handle, Database);
949 end;
950 
951 function TZMySQLBaseDriver.SetOptions(Handle: PZMySQLConnect;
952  Option: TMySQLOption; const Arg: Pointer): Integer;
953 begin
954  Result := MYSQL_API.mysql_options(Handle,TMySqlOption(Option), Arg);
955 end;
956 
957 function TZMySQLBaseDriver.Shutdown(Handle: PZMySQLConnect; shutdown_level: TMysqlShutdownLevel = ZPlainMySqlConstants.SHUTDOWN_DEFAULT): Integer;
958 begin
959  Result := MYSQL_API.mysql_shutdown(Handle,shutdown_level);
960 end;
961 
962 function TZMySQLBaseDriver.SetAutocommit(Handle: PZMySQLConnect; mode: Boolean): Boolean;
963 begin
964  Result := MYSQL_API.mysql_autocommit(PMYSQL(Handle), Byte(Ord(Mode))) = 0;
965 end;
966 
967 function TZMySQLBaseDriver.Commit(Handle: PZMySQLConnect): Boolean;
968 begin
969  Result := MYSQL_API.mysql_commit(PMYSQL(Handle)) = 0;
970 end;
971 
972 function TZMySQLBaseDriver.CheckAnotherRowset(Handle: PZMySQLConnect): Boolean;
973 begin
974  Result := MYSQL_API.mysql_more_results (PMYSQL(Handle)) <> 0;
975 end;
976 
977 function TZMySQLBaseDriver.RetrieveNextRowset(Handle: PZMySQLConnect): Integer;
978 begin
979  Result := MYSQL_API.mysql_next_result (PMYSQL(Handle));
980 end;
981 
982 function TZMySQLBaseDriver.Rollback (Handle: PZMySQLConnect): Boolean;
983 begin
984  Result := MYSQL_API.mysql_rollback(PMYSQL(Handle)) = 0;
985 end;
986 
987 function TZMySQLBaseDriver.GetSQLState(Handle: PZMySQLConnect): AnsiString;
988 begin
989  Result := MYSQL_API.mysql_sqlstate (PMYSQL(Handle));
990 end;
991 
992 function TZMySQLBaseDriver.StmtAttrSet(stmt: PZMySqlPrepStmt;
993  option: TMysqlStmtAttrType; arg: Pointer): Byte;
994 begin
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);
1001 end;
1002 
1003 function TZMySQLBaseDriver.GetPreparedAffectedRows(Handle: PZMySqlPrepStmt): Int64;
1004 begin
1005  Result := MYSQL_API.mysql_stmt_affected_rows (PMYSQL_STMT(Handle));
1006 end;
1007 
1008 function TZMySQLBaseDriver.BindParameters(Handle: PZMySqlPrepStmt; bindArray: PZMysqlBindArray): Byte;
1009 begin
1010  Result := MYSQL_API.mysql_stmt_bind_param (PMYSQL_STMT(Handle), pointer(bindArray));
1011 end;
1012 
1013 function TZMySQLBaseDriver.BindResult(Handle: PZMySqlPrepStmt; bindArray: PZMysqlBindArray): Byte;
1014 begin
1015  Result := MYSQL_API.mysql_stmt_bind_result (PMYSQL_STMT(Handle), pointer(bindArray));
1016 end;
1017 
1018 function TZMySQLBaseDriver.ClosePrepStmt (PrepStmtHandle: PZMySqlPrepStmt): PZMySqlPrepStmt;
1019 begin
1020  if (MYSQL_API.mysql_stmt_close(PMYSQL_STMT(PrepStmtHandle)) = 0) then
1021  Result := nil
1022  else
1023  Result := PrepStmtHandle;
1024 end;
1025 
1026 procedure TZMySQLBaseDriver.SeekPreparedData(PrepStmtHandle: PZMySqlPrepStmt; Offset: Cardinal);
1027 begin
1028  MYSQL_API.mysql_stmt_data_seek(PMYSQL_STMT(PrepStmtHandle), Offset);
1029 end;
1030 
1031 function TZMySQLBaseDriver.GetLastPreparedErrorCode(Handle: PZMySqlPrepStmt):Integer;
1032 begin
1033  Result := MYSQL_API.mysql_stmt_errno(PMYSQL_STMT(Handle));
1034 end;
1035 
1036 function TZMySQLBaseDriver.GetLastPreparedError(Handle: PZMySqlPrepStmt):AnsiString;
1037 begin
1038  Result := MYSQL_API.mysql_stmt_error(PMYSQL_STMT(Handle));
1039 end;
1040 
1041 function TZMySQLBaseDriver.ExecuteStmt(Handle: PZMySqlPrepStmt): Integer;
1042 begin
1043  Result := MYSQL_API.mysql_stmt_execute (PMYSQL_STMT(Handle));
1044 end;
1045 
1046 function TZMySQLBaseDriver.FetchBoundResults(Handle: PZMySqlPrepStmt): Integer;
1047 begin
1048  Result := MYSQL_API.mysql_stmt_fetch (PMYSQL_STMT(Handle));
1049 end;
1050 
1051 function TZMySQLBaseDriver.GetPreparedFieldCount(Handle: PZMySqlPrepStmt): Integer;
1052 begin
1053  Result := MYSQL_API.mysql_stmt_field_count(PMYSQL_STMT(Handle));
1054 end;
1055 
1056 function TZMySQLBaseDriver.FreePreparedResult(Handle: PZMySqlPrepStmt): Byte;
1057 begin
1058  Result := MYSQL_API.mysql_stmt_free_result(PMYSQL_STMT(Handle));
1059 end;
1060 
1061 function TZMySQLBaseDriver.InitializePrepStmt (Handle: PZMySQLConnect): PZMySqlPrepStmt;
1062 begin
1063  Result := MYSQL_API.mysql_stmt_init(PMYSQL(Handle));
1064 end;
1065 
1066 function TZMySQLBaseDriver.GetPreparedInsertID(Handle: PZMySqlPrepStmt): Int64;
1067 begin
1068  Result := MYSQL_API.mysql_stmt_insert_id (PMYSQL_STMT(Handle));
1069 end;
1070 
1071 function TZMySQLBaseDriver.GetPreparedNextResult(Handle: PZMySqlPrepStmt): Integer;
1072 begin
1073  if (@MYSQL_API.mysql_stmt_next_result = nil) then
1074  Result := -1 // Successful and there are no more results
1075  else
1076  Result := MYSQL_API.mysql_stmt_next_result (PMYSQL_STMT(Handle));
1077 end;
1078 
1079 function TZMySQLBaseDriver.GetPreparedNumRows(Handle: PZMySqlPrepStmt): Int64;
1080 begin
1081  if (Handle = nil) then
1082  Result := 0
1083  else
1084  Result := MYSQL_API.mysql_stmt_num_rows (PMYSQL_STMT(Handle));
1085 end;
1086 
1087 function TZMySQLBaseDriver.GetPreparedBindMarkers (Handle: PZMySqlPrepStmt): Cardinal;
1088 begin
1089  Result := MYSQL_API.mysql_stmt_param_count (PMYSQL_STMT(Handle));
1090 end;
1091 
1092 function TZMySQLBaseDriver.GetStmtParamMetadata(PrepStmtHandle: PZMySqlPrepStmt): PZMySQLResult;
1093 begin
1094  Result := MYSQL_API.mysql_stmt_param_metadata(PMYSQL_STMT(PrepStmtHandle));
1095 end;
1096 
1097 function TZMySQLBaseDriver.PrepareStmt(PrepStmtHandle: PZMySqlPrepStmt; const Query: PAnsiChar; Length: Integer): Integer;
1098 begin
1099  Result := MYSQL_API.mysql_stmt_prepare(PMYSQL_STMT(PrepStmtHandle), Query, Length);
1100 end;
1101 
1102 function TZMySQLBaseDriver.stmt_reset(PrepStmtHandle: PZMySqlPrepStmt): Byte;
1103 begin
1104  Result := MYSQL_API.mysql_stmt_reset(PrepStmtHandle);
1105 end;
1106 
1107 function TZMySQLBaseDriver.GetPreparedMetaData (Handle: PZMySqlPrepStmt): PZMySQLResult;
1108 begin
1109  Result := MYSQL_API.mysql_stmt_result_metadata (PMYSQL_STMT(Handle));
1110 end;
1111 
1112 function TZMySQLBaseDriver.SeekPreparedRow(Handle: PZMySqlPrepStmt; Row: PZMySQLRowOffset): PZMySQLRowOffset;
1113 begin
1114  Result := MYSQL_API.mysql_stmt_row_seek (PMYSQL_STMT(Handle), Row);
1115 end;
1116 
1117 function TZMySQLBaseDriver.SendPreparedLongData(Handle: PZMySqlPrepStmt;
1118  parameter_number: Cardinal; const data: PAnsiChar; length: Cardinal): Byte;
1119 begin
1120  Result := MYSQL_API.mysql_stmt_send_long_data(PMYSQL_STMT(Handle), parameter_number, data, length);
1121 end;
1122 
1123 function TZMySQLBaseDriver.GetPreparedSQLState(Handle: PZMySqlPrepStmt): PAnsiChar;
1124 begin
1125  Result := MYSQL_API.mysql_stmt_sqlstate (PMYSQL_STMT(Handle));
1126 end;
1127 
1128 function TZMySQLBaseDriver.StorePreparedResult (Handle: PZMySqlPrepStmt): Integer;
1129 begin
1130  Result := MYSQL_API.mysql_stmt_store_result (PMYSQL_STMT(Handle));
1131 end;
1132 
1133 procedure TZMySQLBaseDriver.GetCharacterSetInfo(Handle: PZMySQLConnect; CharSetInfo: PMY_CHARSET_INFO);
1134 begin
1135  MYSQL_API.mysql_get_character_set_info(Handle, CharSetInfo);
1136 end;
1137 
1138 function TZMySQLBaseDriver.GetBindOffsets: MYSQL_BINDOFFSETS;
1139 var
1140  DriverVersion : Integer;
1141 begin
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);
1152  end;
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);
1161  end;
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);
1170  end;
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);
1179  end;
1180  else
1181  if FIsMariaDBDriver and (DriverVersion >= 100000) then //MariaDB 10
1182  begin
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);
1190  end
1191  else
1192  result.buffer_type:=0;
1193  end;
1194 end;
1195 
1196 function TZMySQLBaseDriver.StoreResult(
1197  Handle: PZMySQLConnect): PZMySQLResult;
1198 begin
1199  Result := MYSQL_API.mysql_store_result(Handle);
1200 end;
1201 
1202 function TZMySQLBaseDriver.UseResult(Handle: PZMySQLConnect): PZMySQLResult;
1203 begin
1204  Result := MYSQL_API.mysql_use_result(Handle);
1205 end;
1206 
1207 function TZMySQLBaseDriver.GetLastError(Handle: PZMySQLConnect): PAnsiChar;
1208 begin
1209  Result := MYSQL_API.mysql_error(Handle);
1210 end;
1211 
1212 function TZMySQLBaseDriver.GetFieldType(Field: PZMySQLField): TMysqlFieldTypes;
1213 begin
1214  Result := PMYSQL_FIELD(Field)^._type;
1215 end;
1216 
1217 function TZMySQLBaseDriver.GetFieldFlags(Field: PZMySQLField): Integer;
1218 begin
1219  Result := PMYSQL_FIELD(Field)^.flags;
1220 end;
1221 
1222 function TZMySQLBaseDriver.GetRowCount(Res: PZMySQLResult): Int64;
1223 begin
1224  Result := MYSQL_API.mysql_num_rows(Res);
1225 end;
1226 
1227 function TZMySQLBaseDriver.ResultSetExists(Handle: PZMySQLConnect): Boolean;
1228 begin
1229  result := MYSQL_API.mysql_field_count(Handle)<>0;
1230  // True If statement should return a resultset
1231 end;
1232 
1233 function TZMySQLBaseDriver.GetFieldCount(Res: PZMySQLResult): Integer;
1234 begin
1235  Result := MYSQL_API.mysql_num_fields(Res);
1236 end;
1237 
1238 function TZMySQLBaseDriver.GetFieldDecimals(Field: PZMySQLField): Integer;
1239 begin
1240  Result := PMYSQL_FIELD(Field)^.decimals;
1241 end;
1242 
1243 function TZMySQLBaseDriver.GetFieldCharsetNr(Field: PZMySQLField): UInt;
1244 begin
1245  Result := PMYSQL_FIELD(Field)^.charsetnr;
1246 end;
1247 
1248 function TZMySQLBaseDriver.GetFieldLength(Field: PZMySQLField): ULong;
1249 begin
1250  Result := PMYSQL_FIELD(Field)^.length;
1251 end;
1252 
1253 function TZMySQLBaseDriver.GetFieldMaxLength(Field: PZMySQLField): Integer;
1254 begin
1255  Result := PMYSQL_FIELD(Field)^.max_length;
1256 end;
1257 
1258 function TZMySQLBaseDriver.GetFieldName(Field: PZMySQLField): PAnsiChar;
1259 begin
1260  Result := PMYSQL_FIELD(Field)^.name;
1261 end;
1262 
1263 function TZMySQLBaseDriver.GetFieldTable(Field: PZMySQLField): PAnsiChar;
1264 begin
1265  Result := PMYSQL_FIELD(Field)^.table;
1266 end;
1267 
1268 function TZMySQLBaseDriver.GetFieldOrigTable(Field: PZMySQLField): PAnsiChar;
1269 begin
1270  Result := PMYSQL_FIELD(Field)^.org_table;
1271 end;
1272 
1273 function TZMySQLBaseDriver.GetFieldOrigName(Field: PZMySQLField): PAnsiChar;
1274 begin
1275  Result := PMYSQL_FIELD(Field)^.org_name;
1276 end;
1277 
1278 function TZMySQLBaseDriver.GetFieldData(Row: PZMySQLRow;
1279  Offset: Cardinal): PAnsiChar;
1280 begin
1281  Result := PMYSQL_ROW(ROW)[Offset];
1282 end;
1283 
1284 function TZMySQLBaseDriver.GetLastErrorCode(Handle: PZMySQLConnect): Integer;
1285 begin
1286  Result := MYSQL_API.mysql_errno(PMYSQL(Handle));
1287 end;
1288 
1289 function TZMySQLBaseDriver.GetClientVersion: Integer;
1290 begin
1291  Result := MYSQL_API.mysql_get_client_version;
1292 end;
1293 
1294 function TZMySQLBaseDriver.GetServerVersion(
1295  Handle: PZMySQLConnect): Integer;
1296 begin
1297  Result := MYSQL_API.mysql_get_server_version(Handle);
1298 end;
1299 
1300 procedure TZMySQLBaseDriver.SetDriverOptions(Options: TStrings);
1301 var
1302  PreferedLibrary: String;
1303 begin
1304  PreferedLibrary := Options.Values['Library'];
1305  if PreferedLibrary <> '' then
1306  Loader.AddLocation(PreferedLibrary);
1307  if IsEmbeddedDriver then
1308  BuildServerArguments(Options);
1309 end;
1310 
1311 { TZMySQL41PlainDriver }
1312 
1313 function TZMySQL41PlainDriver.Clone: IZPlainDriver;
1314 begin
1315  Result := TZMySQL41PlainDriver.Create(FTokenizer);
1316 end;
1317 
1318 constructor TZMySQL41PlainDriver.Create(Tokenizer: IZTokenizer);
1319 begin
1320  inherited Create(Tokenizer);
1321  {$IFNDEF UNIX}
1322  FLoader.AddLocation(WINDOWS_DLL41_LOCATION);
1323  {$ELSE}
1324  FLoader.AddLocation(LINUX_DLL41_LOCATION);
1325  {$ENDIF}
1326 end;
1327 
1328 function TZMySQL41PlainDriver.GetProtocol: string;
1329 begin
1330  Result := 'mysql-4.1';
1331 end;
1332 
1333 function TZMySQL41PlainDriver.GetDescription: string;
1334 begin
1335  Result := 'Native Plain Driver for MySQL 4.1+';
1336 end;
1337 
1338 { TZMySQLD41PlainDriver }
1339 
1340 function TZMySQLD41PlainDriver.Clone: IZPlainDriver;
1341 begin
1342  Result := TZMySQLD41PlainDriver.Create(FTokenizer);
1343 end;
1344 
1345 constructor TZMySQLD41PlainDriver.Create(Tokenizer: IZTokenizer);
1346 begin
1347  inherited Create(Tokenizer);
1348  // only include embedded library
1349  FLoader.ClearLocations;
1350  {$IFNDEF MYSQL_STRICT_DLL_LOADING}
1351  {$IFNDEF UNIX}
1352  FLoader.AddLocation(WINDOWS_DLL_LOCATION_EMBEDDED);
1353  {$ELSE}
1354  FLoader.AddLocation(LINUX_DLL_LOCATION_EMBEDDED);
1355  {$ENDIF}
1356  {$ENDIF}
1357  {$IFNDEF UNIX}
1358  FLoader.AddLocation(WINDOWS_DLL41_LOCATION_EMBEDDED);
1359  {$ELSE}
1360  FLoader.AddLocation(LINUX_DLL41_LOCATION_EMBEDDED);
1361  {$ENDIF}
1362  IsEmbeddedDriver := True;
1363 end;
1364 
1365 function TZMySQLD41PlainDriver.GetProtocol: string;
1366 begin
1367  Result := 'mysqld-4.1';
1368 end;
1369 
1370 function TZMySQLD41PlainDriver.GetDescription: string;
1371 begin
1372  Result := 'Native Plain Driver for Embedded MySQL 4.1+';
1373 end;
1374 
1375 { TZMySQL5PlainDriver }
1376 
1377 function TZMySQL5PlainDriver.Clone: IZPlainDriver;
1378 begin
1379  Result := TZMySQL5PlainDriver.Create(FTokenizer);
1380 end;
1381 
1382 procedure TZMySQL5PlainDriver.LoadApi;
1383 begin
1384  inherited LoadApi;
1385 
1386  with Loader do
1387  begin
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');
1390  end;
1391 end;
1392 
1393 procedure TZMySQL5PlainDriver.LoadCodePages;
1394 begin
1395  inherited LoadCodePages;
1396  {MySQL 4.1-5.5}
1397  { MultiByte }
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
1401 end;
1402 
1403 constructor TZMySQL5PlainDriver.Create(Tokenizer: IZTokenizer);
1404 begin
1405  inherited Create(Tokenizer);
1406  {$IFNDEF UNIX}
1407  {$IFNDEF MYSQL_STRICT_DLL_LOADING}
1408  FLoader.AddLocation(MARIADB_LOCATION);
1409  {$ENDIF}
1410  FLoader.AddLocation(WINDOWS_DLL50_LOCATION);
1411  FLoader.AddLocation(WINDOWS_DLL51_LOCATION);
1412  FLoader.AddLocation(WINDOWS_DLL55_LOCATION);
1413  {$ELSE}
1414  {$IFNDEF MYSQL_STRICT_DLL_LOADING}
1415  FLoader.AddLocation(MARIADB_LOCATION);
1416  {$ENDIF}
1417  FLoader.AddLocation(LINUX_DLL50_LOCATION);
1418  FLoader.AddLocation(LINUX_DLL51_LOCATION);
1419  FLoader.AddLocation(LINUX_DLL55_LOCATION);
1420  {$ENDIF}
1421 end;
1422 
1423 function TZMySQL5PlainDriver.GetProtocol: string;
1424 begin
1425  Result := 'mysql-5';
1426 end;
1427 
1428 function TZMySQL5PlainDriver.GetDescription: string;
1429 begin
1430  Result := 'Native Plain Driver for MySQL 5.0+';
1431 end;
1432 
1433 { TZMySQLD5PlainDriver }
1434 
1435 function TZMySQLD5PlainDriver.Clone: IZPlainDriver;
1436 begin
1437  Result := TZMySQLD5PlainDriver.Create(FTokenizer);
1438 end;
1439 
1440 constructor TZMySQLD5PlainDriver.Create(Tokenizer: IZTokenizer);
1441 begin
1442  inherited Create(Tokenizer);
1443  // only include embedded library
1444  FLoader.ClearLocations;
1445  {$IFNDEF MYSQL_STRICT_DLL_LOADING}
1446  {$IFNDEF UNIX}
1447  FLoader.AddLocation(WINDOWS_DLL_LOCATION_EMBEDDED);
1448  {$ELSE}
1449  FLoader.AddLocation(LINUX_DLL_LOCATION_EMBEDDED);
1450  {$ENDIF}
1451  {$ENDIF}
1452  {$IFNDEF UNIX}
1453  FLoader.AddLocation(WINDOWS_DLL50_LOCATION_EMBEDDED);
1454  FLoader.AddLocation(WINDOWS_DLL51_LOCATION_EMBEDDED);
1455  FLoader.AddLocation(WINDOWS_DLL55_LOCATION_EMBEDDED);
1456  {$ELSE}
1457  FLoader.AddLocation(LINUX_DLL50_LOCATION_EMBEDDED);
1458  FLoader.AddLocation(LINUX_DLL51_LOCATION_EMBEDDED);
1459  FLoader.AddLocation(LINUX_DLL55_LOCATION_EMBEDDED);
1460  {$ENDIF}
1461  IsEmbeddedDriver := True;
1462 end;
1463 
1464 function TZMySQLD5PlainDriver.GetProtocol: string;
1465 begin
1466  Result := 'mysqld-5';
1467 end;
1468 
1469 function TZMySQLD5PlainDriver.GetDescription: string;
1470 begin
1471  Result := 'Native Plain Driver for Embedded MySQL 5+';
1472 end;
1473 
1474 { TZMariaDB5PlainDriver }
1475 function TZMariaDB5PlainDriver.Clone: IZPlainDriver;
1476 begin
1477  Result := TZMariaDB5PlainDriver.Create(FTokenizer);
1478 end;
1479 
1480 constructor TZMariaDB5PlainDriver.Create(Tokenizer: IZTokenizer);
1481 begin
1482  inherited Create(Tokenizer);
1483  FLoader.ClearLocations;
1484  FLoader.AddLocation(MARIADB_LOCATION);
1485 end;
1486 
1487 function TZMariaDB5PlainDriver.GetProtocol: string;
1488 begin
1489  Result := 'MariaDB-5';
1490 end;
1491 
1492 function TZMariaDB5PlainDriver.GetDescription: string;
1493 begin
1494  Result := 'Native Plain Driver for MariaDB-5.x';
1495 end;
1496 
1497 end.
1498 
1499