Fix bug #1897916 "SQL error: Unknown system variable NAMES" by using a regular expression for detecting the numeric version. The commonly used mysql versions with numerical suffixes caused this bug, for example "4.0.31-20070605_Debian-5-log".

(Plus: Make PerformConnect more readable.)
This commit is contained in:
Ansgar Becker
2008-02-20 20:59:00 +00:00
parent b584aa5ae4
commit 7e6477552c

View File

@ -24,7 +24,7 @@ uses
SynCompletionProposal, HeidiComp, SynEditMiscClasses, MysqlQuery, SynCompletionProposal, HeidiComp, SynEditMiscClasses, MysqlQuery,
MysqlQueryThread, queryprogress, communication, MysqlConn, Tabs, MysqlQueryThread, queryprogress, communication, MysqlConn, Tabs,
VirtualTrees, createdatabase, tbl_properties, createtable, TntDBGrids, TntClasses, VirtualTrees, createdatabase, tbl_properties, createtable, TntDBGrids, TntClasses,
SynUnicode; SynUnicode, SynRegExpr;
type type
TOrderCol = class(TObject) TOrderCol = class(TObject)
@ -699,8 +699,9 @@ end;
procedure TMDIChild.PerformConnect; procedure TMDIChild.PerformConnect;
var var
charset : String; charset : String;
v : String[10]; v : String[50];
versions : TStringList; v1, v2, v3 : String;
rx : TRegExpr;
begin begin
try try
time_connected := 0; time_connected := 0;
@ -709,46 +710,44 @@ begin
'" on port ' + IntToStr(FMysqlConn.Connection.Port) ); '" on port ' + IntToStr(FMysqlConn.Connection.Port) );
LogSQL( 'Connection-ID: ' + IntToStr( MySQLConn.Connection.GetThreadId ) ); LogSQL( 'Connection-ID: ' + IntToStr( MySQLConn.Connection.GetThreadId ) );
{*** // Detect server version
Detect server version // Be careful with version suffixes, for example: '4.0.31-20070605_Debian-5-log'
}
v := GetVar( 'SELECT VERSION()' ); v := GetVar( 'SELECT VERSION()' );
versions := explode( '.', v ); rx := TRegExpr.Create;
mysql_version := MakeInt( versions[0] ) * 10000 + MakeInt( versions[1] ) * rx.ModifierG := True;
100 + MakeInt( versions[2] ); rx.Expression := '^(\d+)\.(\d+)\.(\d+)';
strHostRunning := FConn.MysqlParams.Host + ' running MySQL-Version ' + v + if rx.Exec(v) then begin
' / Uptime: %s'; v1 := rx.Match[1];
v2 := rx.Match[2];
v3 := rx.Match[3];
end;
rx.Free;
mysql_version := MakeInt(v1) *10000 + MakeInt(v2) *100 + MakeInt(v3);
strHostRunning := FConn.MysqlParams.Host + ' running MySQL-Version ' + v + ' / Uptime: %s';
strHostNotRunning := 'Disconnected from ' + FConn.MysqlParams.Host + '.'; strHostNotRunning := 'Disconnected from ' + FConn.MysqlParams.Host + '.';
// On Re-Connection, try to restore lost properties
{*** {***
SET NAMES statement available since MySQL 4.1.0 . SET NAMES statement available since MySQL 4.1.0 .
Older versions throw a SQL-error: "Unknown system variable 'NAMES'" Older versions throw a SQL-error: "Unknown system variable 'NAMES'"
@see http://lists.phpbar.de/pipermail/opengeodb/2005-September/002455.html @see http://lists.phpbar.de/pipermail/opengeodb/2005-September/002455.html
} }
if ( mysql_version >= 40100 ) then if mysql_version >= 40100 then begin
begin charset := ConvertWindowsCodepageToMysqlCharacterSet(GetACP());
charset := ConvertWindowsCodepageToMysqlCharacterSet( GetACP() ); if charset = '' then begin
if ( charset = '' ) then
begin
LogSQL( 'Could not find a MySQL character set to match the current ' + LogSQL( 'Could not find a MySQL character set to match the current ' +
'Windows ANSI codepage.', true ); 'Windows ANSI codepage.', true );
LogSQL( Format( 'Use SHOW CHARACTER SET to see MySQL character sets; ' + LogSQL( Format( 'Use SHOW CHARACTER SET to see MySQL character sets; ' +
'if you can find one that you are certain matches %d, please report' + 'if you can find one that you are certain matches %d, please report' +
' it via http://rfe.heidisql.com/.', [GetACP()] ), true ); ' it via http://rfe.heidisql.com/.', [GetACP()] ), true );
end end else
else
begin
ExecuteNonQuery( 'SET NAMES ' + charset ); ExecuteNonQuery( 'SET NAMES ' + charset );
end;
end; end;
if ( FMysqlConn.Connection.Database <> '' ) then // On Re-Connection, try to restore lost properties
begin if FMysqlConn.Connection.Database <> '' then
ExecUseQuery( FMysqlConn.Connection.Database ); ExecUseQuery( FMysqlConn.Connection.Database );
end;
except except
on E: Exception do on E: Exception do begin
begin
LogSQL( E.Message, true ); LogSQL( E.Message, true );
Screen.Cursor := crDefault; Screen.Cursor := crDefault;
MessageDlg( E.Message, mtError, [mbOK], 0 ); MessageDlg( E.Message, mtError, [mbOK], 0 );