00001 {*********************************************************}
00002 { }
00003 { Zeos Database Objects }
00004 { MySQL Database Connectivity Classes }
00005 { }
00006 { Originally written by Sergey Seroukhov }
00007 { }
00008 {*********************************************************}
00009
00010 {@********************************************************}
00011 { Copyright (c) 1999-2006 Zeos Development Group }
00012 { }
00013 { License Agreement: }
00014 { }
00015 { This library is distributed in the hope that it will be }
00016 { useful, but WITHOUT ANY WARRANTY; without even the }
00017 { implied warranty of MERCHANTABILITY or FITNESS FOR }
00018 { A PARTICULAR PURPOSE. See the GNU Lesser General }
00019 { Public License for more details. }
00020 { }
00021 { The source code of the ZEOS Libraries and packages are }
00022 { distributed under the Library GNU General Public }
00023 { License (see the file COPYING / COPYING.ZEOS) }
00024 { with the following modification: }
00025 { As a special exception, the copyright holders of this }
00026 { library give you permission to link this library with }
00027 { independent modules to produce an executable, }
00028 { regardless of the license terms of these independent }
00029 { modules, and to copy and distribute the resulting }
00030 { executable under terms of your choice, provided that }
00031 { you also meet, for each linked independent module, }
00032 { the terms and conditions of the license of that module. }
00033 { An independent module is a module which is not derived }
00034 { from or based on this library. If you modify this }
00035 { library, you may extend this exception to your version }
00036 { of the library, but you are not obligated to do so. }
00037 { If you do not wish to do so, delete this exception }
00038 { statement from your version. }
00039 { }
00040 { }
00041 { The project web site is located on: }
00042 { http:
00043 { http:
00044 { svn:
00045 { }
00046 { http:
00047 { http:
00048 { }
00049 { }
00050 { }
00051 { Zeos Development Group. }
00052 {********************************************************@}
00053
00054 unit ZDbcMySql;
00055
00056 interface
00057
00058 {$I ZDbc.inc}
00059
00060 uses
00061 {$IFNDEF VER130BELOW}
00062 Types,
00063 {$ENDIF}
00064 ZCompatibility, Classes, SysUtils, ZDbcIntfs, ZDbcConnection, ZPlainMySqlDriver,
00065 ZDbcLogging, ZTokenizer, ZGenericSqlAnalyser, ZPlainMySqlConstants;
00066
00067 type
00068
00069 {** Implements MySQL Database Driver. }
00070 TZMySQLDriver = class(TZAbstractDriver)
00071 private
00072 {$IFDEF ENABLE_MYSQL_DEPRECATED}
00073 FMySQL320PlainDriver: IZMySQLPlainDriver;
00074 FMySQL323PlainDriver: IZMySQLPlainDriver;
00075 FMySQL40PlainDriver: IZMySQLPlainDriver;
00076 {$ENDIF ENABLE_MYSQL_DEPRECATED}
00077 FMySQL41PlainDriver: IZMySQLPlainDriver;
00078 FMySQL5PlainDriver: IZMySQLPlainDriver;
00079
00080 FMySQLD41PlainDriver: IZMySQLPlainDriver;
00081 FMySQLD5PlainDriver: IZMySQLPlainDriver;
00082 protected
00083 function GetPlainDriver(const Url: string): IZMySQLPlainDriver;
00084 public
00085 constructor Create;
00086 function Connect(const Url: string; Info: TStrings): IZConnection; override;
00087 function GetSupportedProtocols: TStringDynArray; override;
00088 function GetMajorVersion: Integer; override;
00089 function GetMinorVersion: Integer; override;
00090
00091 function GetTokenizer: IZTokenizer; override;
00092 function GetStatementAnalyser: IZStatementAnalyser; override;
00093 function GetClientVersion(const Url: string): Integer; override;
00094 end;
00095
00096 {** Represents a MYSQL specific connection interface. }
00097 IZMySQLConnection = interface (IZConnection)
00098 ['{68E33DD3-4CDC-4BFC-8A28-E9F2EE94E457}']
00099
00100 function GetPlainDriver: IZMySQLPlainDriver;
00101 function GetConnectionHandle: PZMySQLConnect;
00102 end;
00103
00104 {** Implements MySQL Database Connection. }
00105 TZMySQLConnection = class(TZAbstractConnection, IZMySQLConnection)
00106 private
00107 FCatalog: string;
00108 FPlainDriver: IZMySQLPlainDriver;
00109 FHandle: PZMySQLConnect;
00110 FClientCodePage: string;
00111 public
00112 constructor Create(Driver: IZDriver; const Url: string;
00113 PlainDriver: IZMySQLPlainDriver; const HostName: string; Port: Integer;
00114 const Database: string; const User: string; const Password: string; Info: TStrings);
00115 destructor Destroy; override;
00116
00117 function CreateRegularStatement(Info: TStrings): IZStatement; override;
00118 function CreatePreparedStatement(const SQL: string; Info: TStrings):
00119 IZPreparedStatement; override;
00120
00121 procedure Commit; override;
00122 procedure Rollback; override;
00123
00124 function PingServer: Integer; override;
00125 function EscapeString(Value : String) : String; override;
00126
00127 procedure Open; override;
00128 procedure Close; override;
00129
00130 procedure SetCatalog(const Catalog: string); override;
00131 function GetCatalog: string; override;
00132
00133 procedure SetTransactionIsolation(Level: TZTransactIsolationLevel); override;
00134 procedure SetAutoCommit(AutoCommit: Boolean); override;
00135 {ADDED by fduenas 15-06-2006}
00136 function GetClientVersion: Integer; override;
00137 function GetHostVersion: Integer; override;
00138 {END ADDED by fduenas 15-06-2006}
00139 function GetPlainDriver: IZMySQLPlainDriver;
00140 function GetConnectionHandle: PZMySQLConnect;
00141 function GetDescription: AnsiString;
00142 end;
00143
00144
00145 var
00146 {** The common driver manager object. }
00147 MySQLDriver: IZDriver;
00148
00149 implementation
00150
00151 uses
00152 ZMessages, ZSysUtils, ZDbcUtils, ZDbcMySqlStatement, ZMySqlToken,
00153 ZDbcMySqlUtils, ZDbcMySqlMetadata, ZMySqlAnalyser, TypInfo, Math;
00154
00155 { TZMySQLDriver }
00156
00157 {**
00158 Constructs this object with default properties.
00159 }
00160 constructor TZMySQLDriver.Create;
00161 begin
00162 {$IFDEF ENABLE_MYSQL_DEPRECATED}
00163 FMySQL320PlainDriver := TZMySQL320PlainDriver.Create;
00164 FMySQL323PlainDriver := TZMySQL323PlainDriver.Create;
00165 FMySQL40PlainDriver := TZMySQL40PlainDriver.Create;
00166 {$ENDIF ENABLE_MYSQL_DEPRECATED}
00167 FMySQL41PlainDriver := TZMySQL41PlainDriver.Create;
00168 FMySQL5PlainDriver := TZMySQL5PlainDriver.Create;
00169
00170 FMySQLD41PlainDriver := TZMySQLD41PlainDriver.Create;
00171 FMySQLD5PlainDriver := TZMySQLD5PlainDriver.Create;
00172 end;
00173
00174 {**
00175 Attempts to make a database connection to the given URL.
00176 The driver should return "null" if it realizes it is the wrong kind
00177 of driver to connect to the given URL. This will be common, as when
00178 the JDBC driver manager is asked to connect to a given URL it passes
00179 the URL to each loaded driver in turn.
00180
00181 <P>The driver should raise a SQLException if it is the right
00182 driver to connect to the given URL, but has trouble connecting to
00183 the database.
00184
00185 <P>The java.util.Properties argument can be used to passed arbitrary
00186 string tag/value pairs as connection arguments.
00187 Normally at least "user" and "password" properties should be
00188 included in the Properties.
00189
00190 @param url the URL of the database to which to connect
00191 @param info a list of arbitrary string tag/value pairs as
00192 connection arguments. Normally at least a "user" and
00193 "password" property should be included.
00194 @return a <code>Connection</code> object that represents a
00195 connection to the URL
00196 }
00197 function TZMySQLDriver.Connect(const Url: string; Info: TStrings): IZConnection;
00198 var
00199 TempInfo: TStrings;
00200 HostName, Database, UserName, Password: string;
00201 Port: Integer;
00202 PlainDriver: IZMySQLPlainDriver;
00203 begin
00204 TempInfo := TStringList.Create;
00205 try
00206 PlainDriver := GetPlainDriver(Url);
00207 ResolveDatabaseUrl(Url, Info, HostName, Port, Database,
00208 UserName, Password, TempInfo);
00209
00210 if PlainDriver <> nil then
00211 PlainDriver.BuildArguments(TempInfo);
00212 Result := TZMySQLConnection.Create(Self, Url, PlainDriver, HostName, Port,
00213 Database, UserName, Password, TempInfo);
00214 finally
00215 TempInfo.Free;
00216 end;
00217 end;
00218
00219 {**
00220 Gets the driver's major version number. Initially this should be 1.
00221 @return this driver's major version number
00222 }
00223 function TZMySQLDriver.GetMajorVersion: Integer;
00224 begin
00225 Result := 1;
00226 end;
00227
00228 {**
00229 Gets the driver's minor version number. Initially this should be 0.
00230 @return this driver's minor version number
00231 }
00232 function TZMySQLDriver.GetMinorVersion: Integer;
00233 begin
00234 Result := 1;
00235 end;
00236
00237 {**
00238 Gets a SQL syntax tokenizer.
00239 @returns a SQL syntax tokenizer object.
00240 }
00241 function TZMySQLDriver.GetTokenizer: IZTokenizer;
00242 begin
00243 if Tokenizer = nil then
00244 Tokenizer := TZMySQLTokenizer.Create;
00245 Result := Tokenizer;
00246 end;
00247
00248 {**
00249 Creates a statement analyser object.
00250 @returns a statement analyser object.
00251 }
00252 function TZMySQLDriver.GetStatementAnalyser: IZStatementAnalyser;
00253 begin
00254 if Analyser = nil then
00255 Analyser := TZMySQLStatementAnalyser.Create;
00256 Result := Analyser;
00257 end;
00258
00259 {**
00260 Get a name of the supported subprotocol.
00261 For example: mysql, oracle8 or postgresql72
00262 }
00263 function TZMySQLDriver.GetSupportedProtocols: TStringDynArray;
00264 var i : smallint;
00265 begin
00266 {$IFDEF ENABLE_MYSQL_DEPRECATED}
00267 SetLength(Result, 8);
00268 {$ELSE}
00269 SetLength(Result, 5);
00270 {$ENDIF ENABLE_MYSQL_DEPRECATED}
00271 i := 0;
00272
00273 Result[i] := 'mysql';
00274 inc(i);
00275
00276 {$IFDEF ENABLE_MYSQL_DEPRECATED}
00277 Result[i] := FMySQL320PlainDriver.GetProtocol;
00278 inc(i);
00279 Result[i] := FMySQL323PlainDriver.GetProtocol;
00280 inc(i);
00281 Result[i] := FMySQL40PlainDriver.GetProtocol;
00282 inc(i);
00283 {$ENDIF ENABLE_MYSQL_DEPRECATED}
00284 Result[i] := FMySQL41PlainDriver.GetProtocol;
00285 inc(i);
00286 Result[i] := FMySQL5PlainDriver.GetProtocol;
00287 inc(i);
00288
00289 Result[i] := FMySQLD41PlainDriver.GetProtocol;
00290 inc(i);
00291 Result[i] := FMySQLD5PlainDriver.GetProtocol;
00292 end;
00293
00294 {**
00295 Gets plain driver for selected protocol.
00296 @param Url a database connection URL.
00297 @return a selected protocol.
00298 }
00299 function TZMySQLDriver.GetPlainDriver(const Url: string): IZMySQLPlainDriver;
00300 var
00301 Protocol: string;
00302 begin
00303 Protocol := ResolveConnectionProtocol(Url, GetSupportedProtocols);
00304 if false then
00305 {$IFDEF ENABLE_MYSQL_DEPRECATED}
00306 else if Protocol = FMySQL320PlainDriver.GetProtocol then
00307 Result := FMySQL320PlainDriver
00308 else if Protocol = FMySQL323PlainDriver.GetProtocol then
00309 Result := FMySQL323PlainDriver
00310 else if Protocol = FMySQL40PlainDriver.GetProtocol then
00311 Result := FMySQL40PlainDriver
00312 {$ENDIF ENABLE_MYSQL_DEPRECATED}
00313 else if Protocol = FMySQL41PlainDriver.GetProtocol then
00314 Result := FMySQL41PlainDriver
00315 else if Protocol = FMySQL5PlainDriver.GetProtocol then
00316 Result := FMySQL5PlainDriver
00317
00318 else if Protocol = FMySQLD41PlainDriver.GetProtocol then
00319 Result := FMySQLD41PlainDriver
00320 else if Protocol = FMySQLD5PlainDriver.GetProtocol then
00321 Result := FMySQLD5PlainDriver
00322
00323 else
00324 Result := FMySQL5PlainDriver;
00325 Result.Initialize;
00326 end;
00327
00328 {**
00329 Returns the version of the plain driver library that will be used to open a connection
00330 to the given URL.
00331 @param url the URL of the database
00332 @return the version number of the plain driver library for the give URL
00333 }
00334 function TZMySQLDriver.GetClientVersion(const Url: string): Integer;
00335 begin
00336 Result := ConvertMySQLVersionToSQLVersion(GetPlainDriver(Url).GetClientVersion);
00337 end;
00338
00339 { TZMySQLConnection }
00340
00341 {**
00342 Constructs this object and assignes the main properties.
00343 @param Driver the parent ZDBC driver.
00344 @param PlainDriver a MySQL plain driver.
00345 @param HostName a name of the host.
00346 @param Port a port number (0 for default port).
00347 @param Database a name pof the database.
00348 @param User a user name.
00349 @param Password a user password.
00350 @param Info a string list with extra connection parameters.
00351 }
00352 constructor TZMySQLConnection.Create(Driver: IZDriver; const Url: string;
00353 PlainDriver: IZMySQLPlainDriver; const HostName: string; Port: Integer;
00354 const Database, User, Password: string; Info: TStrings);
00355 begin
00356 inherited Create(Driver, Url, HostName, Port, Database, User, Password, Info,
00357 TZMySQLDatabaseMetadata.Create(Self, Url, Info));
00358
00359 { Sets a default properties }
00360 FPlainDriver := PlainDriver;
00361 if Self.Port = 0 then Self.Port := MYSQL_PORT;
00362 AutoCommit := True;
00363 TransactIsolationLevel := tiNone;
00364
00365 { Processes connection properties. }
00366 FClientCodePage := Trim(Info.Values['codepage']);
00367
00368 Open;
00369 end;
00370
00371 {**
00372 Destroys this object and cleanups the memory.
00373 }
00374 destructor TZMySQLConnection.Destroy;
00375 begin
00376 inherited Destroy;
00377 end;
00378
00379 {**
00380 Opens a connection to database server with specified parameters.
00381 }
00382 procedure TZMySQLConnection.Open;
00383 var
00384 LogMessage: string;
00385 OldLevel: TZTransactIsolationLevel;
00386 OldAutoCommit: Boolean;
00387 ConnectTimeout: Integer;
00388 SQL: PChar;
00389 ClientFlag : Cardinal;
00390 SslCa, SslCaPath, SslKey, SslCert, SslCypher : PChar;
00391 myopt: TZMySQLOption;
00392 sMyOpt: string;
00393 my_client_Opt:TMYSQL_CLIENT_OPTIONS;
00394 sMy_client_Opt:String;
00395 begin
00396 if not Closed then Exit;
00397
00398 LogMessage := Format('CONNECT TO "%s" AS USER "%s"', [Database, User]);
00399
00400 FPlainDriver.Init(FHandle);
00401 try
00402 { Sets a default port number. }
00403 if Port = 0 then Port := MYSQL_PORT;
00404
00405 { Turn on compression protocol. }
00406 if StrToBoolEx(Info.Values['compress']) then
00407 FPlainDriver.SetOptions(FHandle, MYSQL_OPT_COMPRESS, nil);
00408 { Sets connection timeout. }
00409 ConnectTimeout := StrToIntDef(Info.Values['timeout'], 0);
00410 if ConnectTimeout >= 0 then
00411 begin
00412 FPlainDriver.SetOptions(FHandle, MYSQL_OPT_CONNECT_TIMEOUT,
00413 PChar(@ConnectTimeout));
00414 end;
00415
00416 (*Added lines to handle option parameters 21 november 2007 marco cotroneo*)
00417 for myopt := low(TZMySQLOption) to high(TZMySQLOption) do
00418 begin
00419 sMyOpt:= GetEnumName(typeInfo(TZMySQLOption), integer(myOpt));
00420 if Info.Values[sMyOpt] <> '' then
00421 begin
00422 FPlainDriver.SetOptions(FHandle, myopt,
00423 PChar(Info.Values[sMyOpt]));
00424 end;
00425 end;
00426
00427 { Set ClientFlag }
00428 ClientFlag := 0;
00429 if Not StrToBoolEx(Info.Values['dbless'])
00430 then ClientFlag := trunc(power(2, GetEnumValue( TypeInfo(TMYSQL_CLIENT_OPTIONS),'_CLIENT_CONNECT_WITH_DB')));
00431
00432 for my_client_Opt := low(TMYSQL_CLIENT_OPTIONS) to high(TMYSQL_CLIENT_OPTIONS) do
00433 begin
00434 sMy_client_Opt:= GetEnumName(typeInfo(TMYSQL_CLIENT_OPTIONS), integer(my_client_Opt));
00435 if StrToBoolEx(Info.Values[sMy_client_Opt]) then
00436 ClientFlag:= ClientFlag or trunc(power(2, GetEnumValue(TypeInfo(TMYSQL_CLIENT_OPTIONS),sMy_client_Opt)));
00437 end;
00438
00439 { Set SSL properties before connect}
00440 SslKey := nil;
00441 SslCert := nil;
00442 SslCa := nil;
00443 SslCaPath := nil;
00444 SslCypher := nil;
00445 if StrToBoolEx(Info.Values['MYSQL_SSL']) then
00446 begin
00447 If Info.Values['MYSQL_SSL_KEY'] <> '' then SslKey := PChar(Info.Values['MYSQL_SSL_KEY']);
00448 If Info.Values['MYSQL_SSL_CERT'] <> '' then SslCert := PChar(Info.Values['MYSQL_SSL_CERT']);
00449 If Info.Values['MYSQL_SSL_CA'] <> '' then SslCa := PChar(Info.Values['MYSQL_SSL_CA']);
00450 If Info.Values['MYSQL_SSL_CAPATH'] <> '' then SslCaPath := PChar(Info.Values['MYSQL_SSL_CAPATH']);
00451 If Info.Values['MYSQL_SSL_CYPHER'] <> '' then SslCypher := PChar(Info.Values['MYSQL_SSL_CYPHER']);
00452 FPlainDriver.SslSet(FHandle, SslKey, SslCert, SslCa, SslCaPath, SslCypher);
00453 DriverManager.LogMessage(lcConnect, FPlainDriver.GetProtocol, 'SSL options set');
00454 end;
00455
00456 { Connect to MySQL database. }
00457 if FPlainDriver.RealConnect(FHandle, PChar(HostName), PChar(User),
00458 PChar(Password), PChar(Database), Port, nil,
00459 ClientFlag) = nil then
00460 begin
00461 CheckMySQLError(FPlainDriver, FHandle, lcConnect, LogMessage);
00462 DriverManager.LogError(lcConnect, FPlainDriver.GetProtocol, LogMessage,
00463 0, SUnknownError);
00464 raise EZSQLException.Create(SCanNotConnectToServer);
00465 end;
00466 DriverManager.LogMessage(lcConnect, FPlainDriver.GetProtocol, LogMessage);
00467
00468 { Sets a client codepage. }
00469 if FClientCodePage <> '' then
00470 begin
00471 SQL := PChar(Format('SET CHARACTER SET %s', [FClientCodePage]));
00472 FPlainDriver.ExecQuery(FHandle, SQL);
00473 CheckMySQLError(FPlainDriver, FHandle, lcExecute, SQL);
00474 DriverManager.LogMessage(lcExecute, FPlainDriver.GetProtocol, SQL);
00475 end;
00476
00477 { Sets transaction isolation level. }
00478 OldLevel := TransactIsolationLevel;
00479 TransactIsolationLevel := tiNone;
00480 SetTransactionIsolation(OldLevel);
00481
00482 { Sets an auto commit mode. }
00483 OldAutoCommit := AutoCommit;
00484 AutoCommit := True;
00485 SetAutoCommit(OldAutoCommit);
00486 except
00487 FPlainDriver.Close(FHandle);
00488 FPlainDriver.Despose(FHandle);
00489 FHandle := nil;
00490 raise;
00491 end;
00492
00493 inherited Open;
00494 end;
00495
00496 {**
00497 Ping Current Connection's server, if client was disconnected,
00498 the connection is resumed.
00499 @return 0 if succesfull or error code if any error occurs
00500 }
00501 function TZMySQLConnection.PingServer: Integer;
00502 const
00503 PING_ERROR_ZEOSCONNCLOSED = -1;
00504 var
00505 Closing: boolean;
00506 begin
00507 Closing := FHandle = nil;
00508 if Closed or Closing then Result := PING_ERROR_ZEOSCONNCLOSED
00509 else Result := FPlainDriver.Ping(FHandle);
00510 end;
00511
00512 {**
00513 Escape a string so it's acceptable for the Connection's server.
00514 @param value string that should be escaped
00515 @return Escaped string
00516 }
00517 function TZMySQLConnection.EscapeString(Value : String) : String;
00518 var
00519 Closing: boolean;
00520 Inlength, outlength: integer;
00521 Outbuffer: String;
00522 begin
00523 InLength := Length(Value);
00524 // OutLength := 0;
00525 Setlength(Outbuffer,Inlength*2+1);
00526 Closing := FHandle = nil;
00527 //RealConnect needs database connection handle
00528 if Closed or Closing then
00529 OutLength := FPlainDriver.GetEscapeString(PAnsiChar(OutBuffer),PAnsiChar(Value),InLength)
00530 else
00531 OutLength := FPlainDriver.GetRealEscapeString(FHandle, PAnsiChar(OutBuffer),PAnsiChar(Value),InLength);
00532 Setlength(Outbuffer,OutLength);
00533 Result := Outbuffer;
00534 end;
00535
00536 {**
00537 Creates a <code>Statement</code> object for sending
00538 SQL statements to the database.
00539 SQL statements without parameters are normally
00540 executed using Statement objects. If the same SQL statement
00541 is executed many times, it is more efficient to use a
00542 <code>PreparedStatement</code> object.
00543 <P>
00544 Result sets created using the returned <code>Statement</code>
00545 object will by default have forward-only type and read-only concurrency.
00546
00547 @param Info a statement parameters.
00548 @return a new Statement object
00549 }
00550 function TZMySQLConnection.CreateRegularStatement(Info: TStrings):
00551 IZStatement;
00552 begin
00553 if IsClosed then Open;
00554 Result := TZMySQLStatement.Create(FPlainDriver, Self, Info, FHandle);
00555 end;
00556
00557 {**
00558 Creates a <code>PreparedStatement</code> object for sending
00559 parameterized SQL statements to the database.
00560
00561 A SQL statement with or without IN parameters can be
00562 pre-compiled and stored in a PreparedStatement object. This
00563 object can then be used to efficiently execute this statement
00564 multiple times.
00565
00566 <P><B>Note:</B> This method is optimized for handling
00567 parametric SQL statements that benefit from precompilation. If
00568 the driver supports precompilation,
00569 the method <code>prepareStatement</code> will send
00570 the statement to the database for precompilation. Some drivers
00571 may not support precompilation. In this case, the statement may
00572 not be sent to the database until the <code>PreparedStatement</code> is
00573 executed. This has no direct effect on users; however, it does
00574 affect which method throws certain SQLExceptions.
00575
00576 Result sets created using the returned PreparedStatement will have
00577 forward-only type and read-only concurrency, by default.
00578
00579 @param sql a SQL statement that may contain one or more '?' IN
00580 parameter placeholders
00581 @param Info a statement parameters.
00582 @return a new PreparedStatement object containing the
00583 pre-compiled statement
00584 }
00585 function TZMySQLConnection.CreatePreparedStatement(const SQL: string;
00586 Info: TStrings): IZPreparedStatement;
00587 begin
00588 if IsClosed then Open;
00589 Result := TZMySQLPreparedStatement.Create(FPlainDriver, Self, SQL,
00590 Info, FHandle);
00591 end;
00592
00593 {**
00594 Makes all changes made since the previous
00595 commit/rollback permanent and releases any database locks
00596 currently held by the Connection. This method should be
00597 used only when auto-commit mode has been disabled.
00598 @see #setAutoCommit
00599 }
00600 procedure TZMySQLConnection.Commit;
00601 begin
00602 if (TransactIsolationLevel <> tiNone) and (AutoCommit <> True)
00603 and not Closed then
00604 begin
00605 If not FPlaindriver.Commit(FHandle) then
00606 CheckMySQLError(FPlainDriver, FHandle, lcExecute, 'Native Commit call');
00607 DriverManager.LogMessage(lcExecute, FPlainDriver.GetProtocol, 'Native Commit call');
00608 end;
00609 end;
00610
00611 {**
00612 Drops all changes made since the previous
00613 commit/rollback and releases any database locks currently held
00614 by this Connection. This method should be used only when auto-
00615 commit has been disabled.
00616 @see #setAutoCommit
00617 }
00618 procedure TZMySQLConnection.Rollback;
00619 begin
00620 if (TransactIsolationLevel <> tiNone) and (AutoCommit <> True)
00621 and not Closed then
00622 begin
00623 If not FPlaindriver.Rollback(FHandle) then
00624 CheckMySQLError(FPlainDriver, FHandle, lcExecute, 'Native Rollback call');
00625 DriverManager.LogMessage(lcExecute, FPlainDriver.GetProtocol, 'Native Rollback call');
00626 end;
00627 end;
00628
00629 {**
00630 Releases a Connection's database and JDBC resources
00631 immediately instead of waiting for
00632 them to be automatically released.
00633
00634 <P><B>Note:</B> A Connection is automatically closed when it is
00635 garbage collected. Certain fatal errors also result in a closed
00636 Connection.
00637 }
00638 procedure TZMySQLConnection.Close;
00639 var
00640 LogMessage: string;
00641 begin
00642 if not Closed then
00643 begin
00644 FPlainDriver.Close(FHandle);
00645 FPlainDriver.Despose(FHandle);
00646 FHandle := nil;
00647 LogMessage := Format('DISCONNECT FROM "%s"', [Database]);
00648 DriverManager.LogMessage(lcDisconnect, FPlainDriver.GetProtocol, LogMessage);
00649 end;
00650 inherited Close;
00651 end;
00652
00653 {**
00654 Gets a selected catalog name.
00655 @return a selected catalog name.
00656 }
00657 function TZMySQLConnection.GetCatalog: string;
00658 begin
00659 Result := FCatalog;
00660 end;
00661
00662 {**
00663 Sets a new selected catalog name.
00664 @param Catalog a selected catalog name.
00665 }
00666 procedure TZMySQLConnection.SetCatalog(const Catalog: string);
00667 begin
00668 FCatalog := Catalog;
00669 end;
00670
00671 {**
00672 Sets a new transact isolation level.
00673 @param Level a new transact isolation level.
00674 }
00675 procedure TZMySQLConnection.SetTransactionIsolation(
00676 Level: TZTransactIsolationLevel);
00677 var
00678 SQL: PChar;
00679 testResult: Integer;
00680 begin
00681 if TransactIsolationLevel <> Level then
00682 begin
00683 inherited SetTransactionIsolation(Level);
00684 testResult := 1;
00685 if not Closed then
00686 begin
00687 case TransactIsolationLevel of
00688 tiNone, tiReadUncommitted:
00689 begin
00690 SQL := 'SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED';
00691 testResult := FPlainDriver.ExecQuery(FHandle, SQL);
00692 end;
00693 tiReadCommitted:
00694 begin
00695 SQL := 'SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED';
00696 testResult := FPlainDriver.ExecQuery(FHandle, SQL);
00697 end;
00698 tiRepeatableRead:
00699 begin
00700 SQL := 'SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ';
00701 testResult := FPlainDriver.ExecQuery(FHandle, SQL);
00702 end;
00703 tiSerializable:
00704 begin
00705 SQL := 'SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE';
00706 testResult := FPlainDriver.ExecQuery(FHandle, SQL);
00707 end;
00708 else
00709 SQL := '';
00710 end;
00711 if (testResult <> 0) then
00712 CheckMySQLError(FPlainDriver, FHandle, lcExecute, SQL);
00713 if SQL <> '' then
00714 DriverManager.LogMessage(lcExecute, FPlainDriver.GetProtocol, SQL);
00715 end;
00716 end;
00717 end;
00718
00719 {**
00720 Sets this connection's auto-commit mode.
00721 If a connection is in auto-commit mode, then all its SQL
00722 statements will be executed and committed as individual
00723 transactions. Otherwise, its SQL statements are grouped into
00724 transactions that are terminated by a call to either
00725 the method <code>commit</code> or the method <code>rollback</code>.
00726 By default, new connections are in auto-commit mode.
00727
00728 The commit occurs when the statement completes or the next
00729 execute occurs, whichever comes first. In the case of
00730 statements returning a ResultSet, the statement completes when
00731 the last row of the ResultSet has been retrieved or the
00732 ResultSet has been closed. In advanced cases, a single
00733 statement may return multiple results as well as output
00734 parameter values. In these cases the commit occurs when all results and
00735 output parameter values have been retrieved.
00736
00737 @param autoCommit true enables auto-commit; false disables auto-commit.
00738 }
00739 procedure TZMySQLConnection.SetAutoCommit(AutoCommit: Boolean);
00740 begin
00741 if AutoCommit <> Self.AutoCommit then
00742 begin
00743 inherited SetAutoCommit(AutoCommit);
00744
00745 if not Closed then
00746 begin
00747 if not FPlaindriver.SetAutocommit(FHandle, AutoCommit) then
00748 CheckMySQLError(FPlainDriver, FHandle, lcExecute, 'Native SetAutoCommit '+BoolToStrEx(AutoCommit)+'call');
00749 DriverManager.LogMessage(lcExecute, FPlainDriver.GetProtocol, 'Native SetAutoCommit '+BoolToStrEx(AutoCommit)+'call');
00750 end;
00751 end;
00752 end;
00753
00754 {**
00755 Gets client's full version number.
00756 The format of the version returned must be XYYYZZZ where
00757 X = Major version
00758 YYY = Minor version
00759 ZZZ = Sub version
00760 @return this clients's full version number
00761 }
00762 function TZMySQLConnection.GetClientVersion: Integer;
00763 begin
00764 Result := ConvertMySQLVersionToSQLVersion( FPlainDriver.GetClientVersion );
00765 end;
00766
00767 {**
00768 Gets server's full version number.
00769 The format of the returned version must be XYYYZZZ where
00770 X = Major version
00771 YYY = Minor version
00772 ZZZ = Sub version
00773 @return this clients's full version number
00774 }
00775 function TZMySQLConnection.GetHostVersion: Integer;
00776 begin
00777 Result := ConvertMySQLVersionToSQLVersion( FPlainDriver.GetServerVersion(FHandle) );
00778 CheckMySQLError(FPlainDriver, FHandle, lcExecute, 'mysql_get_server_version()');
00779 end;
00780
00781 {**
00782 Gets a reference to MySQL connection handle.
00783 @return a reference to MySQL connection handle.
00784 }
00785 function TZMySQLConnection.GetConnectionHandle: PZMySQLConnect;
00786 begin
00787 Result := FHandle;
00788 end;
00789
00790 {**
00791 Gets a MySQL plain driver interface.
00792 @return a MySQL plain driver interface.
00793 }
00794 function TZMySQLConnection.GetPlainDriver: IZMySQLPlainDriver;
00795 begin
00796 Result := FPlainDriver;
00797 End;
00798
00799 function TZMySQLConnection.GetDescription: AnsiString;
00800 begin
00801 Result := self.FPlainDriver.GetDescription;
00802 end;
00803
00804 initialization
00805 MySQLDriver := TZMySQLDriver.Create;
00806 DriverManager.RegisterDriver(MySQLDriver);
00807 finalization
00808 if DriverManager <> nil then
00809 DriverManager.DeregisterDriver(MySQLDriver);
00810 MySQLDriver := nil;
00811 end.
00812