Reimplement ANSI support to keep nutcases armed with v3.23 mysql servers happy.

Fixes issue #497.
This commit is contained in:
rosenfield.albert
2008-06-16 21:20:15 +00:00
parent a2609eee22
commit ee1feb5521
4 changed files with 31 additions and 10 deletions

View File

@ -99,6 +99,7 @@ type
function GetPlainDriver: IZMySQLPlainDriver;
function GetConnectionHandle: PZMySQLConnect;
function GetAnsiMode: Boolean;
end;
{** Implements MySQL Database Connection. }
@ -107,7 +108,7 @@ type
FCatalog: string;
FPlainDriver: IZMySQLPlainDriver;
FHandle: PZMySQLConnect;
FClientCodePage: string;
FAnsiMode: Boolean;
public
constructor Create(Driver: IZDriver; const Url: string;
PlainDriver: IZMySQLPlainDriver; const HostName: string; Port: Integer;
@ -141,6 +142,7 @@ type
function GetPlainDriver: IZMySQLPlainDriver;
function GetConnectionHandle: PZMySQLConnect;
function GetDescription: AnsiString;
function GetAnsiMode: Boolean;
end;
@ -358,9 +360,6 @@ begin
AutoCommit := True;
TransactIsolationLevel := tiNone;
{ Processes connection properties. }
FClientCodePage := Trim(Info.Values['codepage']);
Open;
end;
@ -438,10 +437,14 @@ begin
end;
DriverManager.LogMessage(lcConnect, FPlainDriver.GetProtocol, LogMessage);
FAnsiMode := FPlainDriver.GetServerVersion(FHandle) < 40100;
{ Sets a client codepage. }
FPlainDriver.SetCharacterSet(FHandle, 'utf8');
CheckMySQLError(FPlainDriver, FHandle, lcExecute, LogMessage);
DriverManager.LogMessage(lcExecute, FPlainDriver.GetProtocol, LogMessage);
if not FAnsiMode then begin
FPlainDriver.SetCharacterSet(FHandle, 'utf8');
CheckMySQLError(FPlainDriver, FHandle, lcExecute, LogMessage);
DriverManager.LogMessage(lcExecute, FPlainDriver.GetProtocol, LogMessage);
end;
{ Sets transaction isolation level. }
OldLevel := TransactIsolationLevel;
@ -781,6 +784,11 @@ begin
Result := self.FPlainDriver.GetDescription;
end;
function TZMySQLConnection.GetAnsiMode: Boolean;
begin
Result := FAnsiMode;
end;
initialization
MySQLDriver := TZMySQLDriver.Create;
DriverManager.RegisterDriver(MySQLDriver);

View File

@ -269,7 +269,10 @@ begin
// thus the value returned below will always be 0. Same goes for prepared
// statements, unless STMT_ATTR_UPDATE_MAX_LENGTH is specified.
FieldWidthMax := FPlainDriver.GetFieldMaxLength(FieldHandle);
if FPlainDriver.GetFieldCollationId(FieldHandle) <> COLLATION_BINARY then begin
if
(FPlainDriver.GetFieldCollationId(FieldHandle) <> COLLATION_BINARY) and
(FPlainDriver.GetFieldCollationId(FieldHandle) <> COLLATION_NONE)
then begin
// Results are always utf-8. The MySQL utf-8 encoder can produce sequences that
// consist of up to 3 bytes per character. That's the number which the MySQL
// C API will return when queried, since the server (and the driver) returns
@ -419,7 +422,10 @@ end;
function TZMySQLResultSet.GetUnicodeString(ColumnIndex: Integer): WideString;
begin
Result := UTF8Decode(GetRawData(ColumnIndex));
if not ((Statement.GetConnection) as IZMySQLConnection).GetAnsiMode then
Result := UTF8Decode(GetRawData(ColumnIndex))
else
Result := WideString(GetRawData(ColumnIndex));
end;
{**

View File

@ -177,9 +177,13 @@ end;
given query; never <code>null</code>
}
function TZMySQLStatement.ExecuteQuery(const SQL: WideString): IZResultSet;
var
nativeSql: string;
begin
Result := nil;
if FPlainDriver.ExecQuery(FHandle, PChar(UTF8Encode(SQL))) = 0 then
if not (Connection as IZMySQLConnection).GetAnsiMode then nativeSql := UTF8Encode(SQL)
else nativeSql := String(SQL);
if FPlainDriver.ExecQuery(FHandle, PChar(nativeSql)) = 0 then
begin
DriverManager.LogMessage(lcExecute, FPlainDriver.GetProtocol, SQL);
{$IFDEF ENABLE_MYSQL_DEPRECATED}

View File

@ -153,6 +153,9 @@ const
_CLIENT_REMEMBER_OPTIONS = 2147483648; {Enable/disable multi-results }
COLLATION_BINARY = 63;
// Equivalent to COLLATION_BINARY, this is what
// a new driver returns when connected to a pre-4.1 server.
COLLATION_NONE = 0;
type
PZMySQLConnect = Pointer;