Code cosmetic in initialization code:

* Move TMainForm.ParseCommandLineParameters to helpers:ParseCommandLine
* Modify ParseCommandLine to work without private statics FCmdlineFilenames and FCmdlineConnectionParams
* Move code from helpers:setLocales to dpr file
* Rename TMainForm.Startup to TMainForm.AfterFormCreate
* Destroy AppSettings explicitly in single instance mode
This commit is contained in:
Ansgar Becker
2012-09-16 16:55:53 +00:00
parent d87ece9287
commit fea0e8e194
3 changed files with 106 additions and 129 deletions

View File

@ -47,18 +47,25 @@ uses
{$R ..\..\res\updater.RES} {$R ..\..\res\updater.RES}
begin begin
SetLocales; // Use MySQL standard format for date/time variables: YYYY-MM-DD HH:MM:SS
// Be aware that Delphi internally converts the slashes in ShortDateFormat to the DateSeparator
FormatSettings.DateSeparator := '-';
FormatSettings.TimeSeparator := ':';
FormatSettings.ShortDateFormat := 'yyyy/mm/dd';
FormatSettings.LongTimeFormat := 'hh:nn:ss';
AppSettings := TAppSettings.Create; AppSettings := TAppSettings.Create;
SecondInstMsgId := RegisterWindowMessage(APPNAME); SecondInstMsgId := RegisterWindowMessage(APPNAME);
if (not AppSettings.ReadBool(asAllowMultipleInstances)) and CheckForSecondInstance then if (not AppSettings.ReadBool(asAllowMultipleInstances)) and CheckForSecondInstance then begin
Application.Terminate AppSettings.Free;
else begin Application.Terminate;
end else begin
Application.Initialize; Application.Initialize;
Application.Title := APPNAME; Application.Title := APPNAME;
Application.UpdateFormatSettings := False; Application.UpdateFormatSettings := False;
Application.CreateForm(TMainForm, MainForm); Application.CreateForm(TMainForm, MainForm);
Application.OnMessage := Mainform.OnMessageHandler; Application.OnMessage := Mainform.OnMessageHandler;
MainForm.Startup; MainForm.AfterFormCreate;
Application.MainFormOnTaskBar := True; Application.MainFormOnTaskBar := True;
Application.Run; Application.Run;
end; end;

View File

@ -267,7 +267,6 @@ type
function UnformatNumber(Val: String): String; function UnformatNumber(Val: String): String;
function FormatNumber( int: Int64; Thousands: Boolean=True): String; Overload; function FormatNumber( int: Int64; Thousands: Boolean=True): String; Overload;
function FormatNumber( flt: Double; decimals: Integer = 0; Thousands: Boolean=True): String; Overload; function FormatNumber( flt: Double; decimals: Integer = 0; Thousands: Boolean=True): String; Overload;
procedure setLocales;
procedure ShellExec(cmd: String; path: String=''; params: String=''); procedure ShellExec(cmd: String; path: String=''; params: String='');
function getFirstWord( text: String ): String; function getFirstWord( text: String ): String;
function FormatByteNumber( Bytes: Int64; Decimals: Byte = 1 ): String; Overload; function FormatByteNumber( Bytes: Int64; Decimals: Byte = 1 ): String; Overload;
@ -322,11 +321,12 @@ type
function ErrorDialog(Msg: string): Integer; overload; function ErrorDialog(Msg: string): Integer; overload;
function ErrorDialog(const Title, Msg: string): Integer; overload; function ErrorDialog(const Title, Msg: string): Integer; overload;
function GetHTMLCharsetByEncoding(Encoding: TEncoding): String; function GetHTMLCharsetByEncoding(Encoding: TEncoding): String;
procedure ParseCommandLine(Parameters: TStringlist;
var ConnectionParams: TConnectionParameters; var FileNames: TStringList);
var var
AppSettings: TAppSettings; AppSettings: TAppSettings;
MutexHandle: THandle = 0; MutexHandle: THandle = 0;
DecimalSeparatorSystemdefault: Char;
implementation implementation
@ -933,27 +933,6 @@ begin
end; end;
{***
Set global variables containing the standard local format for date and time
values. Standard means the MySQL-standard format, which is YYYY-MM-DD HH:MM:SS
@note Be aware that Delphi internally converts the slashes in ShortDateFormat
to the DateSeparator
}
procedure setLocales;
begin
FormatSettings.DateSeparator := '-';
FormatSettings.TimeSeparator := ':';
FormatSettings.ShortDateFormat := 'yyyy/mm/dd';
FormatSettings.LongTimeFormat := 'hh:nn:ss';
if DecimalSeparatorSystemdefault = '' then
DecimalSeparatorSystemdefault := FormatSettings.DecimalSeparator;
FormatSettings.DecimalSeparator := DecimalSeparatorSystemdefault;
end;
{*** {***
Open URL or execute system command Open URL or execute system command
@ -2492,6 +2471,77 @@ begin
end; end;
procedure ParseCommandLine(Parameters: TStringlist;
var ConnectionParams: TConnectionParameters; var FileNames: TStringList);
var
rx: TRegExpr;
AllParams, SessName, Host, User, Pass, Socket: String;
i, Port: Integer;
function GetParamValue(ShortName, LongName: String): String;
begin
Result := '';
rx.Expression := '\s(\-'+ShortName+'|\-\-'+LongName+')\s*\=?\s*([^\-]\S*)';
if rx.Exec(AllParams) then
Result := rx.Match[2];
end;
begin
SessName := '';
FileNames := TStringList.Create;
// Prepend a space, so the regular expression can request a mandantory space
// before each param name including the first one
AllParams := ' ' + ImplodeStr(' ', Parameters);
rx := TRegExpr.Create;
SessName := GetParamValue('d', 'description');
if SessName <> '' then begin
try
ConnectionParams := TConnectionParameters.Create(SessName);
except
on E:Exception do begin
// Session params not found in registry
MainForm.LogSQL(E.Message);
SessName := '';
end;
end;
end;
// Test if params were passed. If given, override previous values loaded from registry.
// Enables the user to log into a session with a different, non-stored user: -dSession -uSomeOther
Host := GetParamValue('h', 'host');
User := GetParamValue('u', 'user');
Pass := GetParamValue('p', 'password');
Socket := GetParamValue('S', 'socket');
Port := StrToIntDef(GetParamValue('P', 'port'), 0);
// Leave out support for startup script, seems reasonable for command line connecting
if (Host <> '') or (User <> '') or (Pass <> '') or (Port <> 0) or (Socket <> '') then begin
if not Assigned(ConnectionParams) then begin
ConnectionParams := TConnectionParameters.Create;
ConnectionParams.SessionPath := SessName;
end;
if Host <> '' then ConnectionParams.Hostname := Host;
if User <> '' then ConnectionParams.Username := User;
if Pass <> '' then ConnectionParams.Password := Pass;
if Port <> 0 then ConnectionParams.Port := Port;
if Socket <> '' then begin
ConnectionParams.Hostname := Socket;
ConnectionParams.NetType := ntMySQL_NamedPipe;
end;
// Ensure we have a session name to pass to InitConnection
if (ConnectionParams.SessionPath = '') and (ConnectionParams.Hostname <> '') then
ConnectionParams.SessionPath := ConnectionParams.Hostname;
end;
// Check for valid filename(s) in parameters
for i:=0 to Parameters.Count-1 do begin
if FileExists(Parameters[i]) then
FileNames.Add(Parameters[i]);
end;
end;
{ Threading stuff } { Threading stuff }

View File

@ -568,7 +568,7 @@ type
procedure WMCopyData(var Msg: TWMCopyData); message WM_COPYDATA; procedure WMCopyData(var Msg: TWMCopyData); message WM_COPYDATA;
procedure FormDestroy(Sender: TObject); procedure FormDestroy(Sender: TObject);
procedure FormCreate(Sender: TObject); procedure FormCreate(Sender: TObject);
procedure Startup; procedure AfterFormCreate;
procedure FormResize(Sender: TObject); procedure FormResize(Sender: TObject);
procedure actUserManagerExecute(Sender: TObject); procedure actUserManagerExecute(Sender: TObject);
procedure actAboutBoxExecute(Sender: TObject); procedure actAboutBoxExecute(Sender: TObject);
@ -908,8 +908,6 @@ type
FFilterTextDatabase, FFilterTextDatabase,
FFilterTextData: String; FFilterTextData: String;
FTreeRefreshInProgress: Boolean; FTreeRefreshInProgress: Boolean;
FCmdlineFilenames: TStringlist;
FCmdlineConnectionParams: TConnectionParameters;
FSearchReplaceExecuted: Boolean; FSearchReplaceExecuted: Boolean;
FDataGridColumnWidthsCustomized: Boolean; FDataGridColumnWidthsCustomized: Boolean;
FSnippetFilenames: TStringList; FSnippetFilenames: TStringList;
@ -935,7 +933,6 @@ type
FCommandStatsQueryCount: Int64; FCommandStatsQueryCount: Int64;
FCommandStatsServerUptime: Integer; FCommandStatsServerUptime: Integer;
procedure ParseCommandLineParameters(Parameters: TStringlist);
procedure SetDelimiter(Value: String); procedure SetDelimiter(Value: String);
procedure DisplayRowCountStats(Sender: TBaseVirtualTree); procedure DisplayRowCountStats(Sender: TBaseVirtualTree);
procedure insertFunction(Sender: TObject); procedure insertFunction(Sender: TObject);
@ -1595,16 +1592,15 @@ end;
{** {**
Check for connection parameters on commandline or show connections form. Check for connection parameters on commandline or show connections form.
} }
procedure TMainForm.Startup; procedure TMainForm.AfterFormCreate;
var var
CmdlineParameters, LastSessions: TStringlist; CmdlineParameters, LastSessions, FileNames: TStringlist;
Connection: TDBConnection; Connection: TDBConnection;
LoadedParams: TConnectionParameters; LoadedParams, ConnectionParams: TConnectionParameters;
LastUpdatecheck, LastStatsCall, LastConnect: TDateTime; LastUpdatecheck, LastStatsCall, LastConnect: TDateTime;
UpdatecheckInterval, i: Integer; UpdatecheckInterval, i: Integer;
DefaultLastrunDate, LastActiveSession: String; DefaultLastrunDate, LastActiveSession: String;
frm : TfrmUpdateCheck; frm : TfrmUpdateCheck;
Connected: Boolean;
StatsCall: THttpDownload; StatsCall: THttpDownload;
SessionPaths: TStringlist; SessionPaths: TStringlist;
DlgResult: TModalResult; DlgResult: TModalResult;
@ -1668,15 +1664,13 @@ begin
end; end;
end; end;
Connected := False;
CmdlineParameters := TStringList.Create; CmdlineParameters := TStringList.Create;
for i:=1 to ParamCount do for i:=1 to ParamCount do
CmdlineParameters.Add(ParamStr(i)); CmdlineParameters.Add(ParamStr(i));
ParseCommandLineParameters(CmdlineParameters); ParseCommandLine(CmdlineParameters, ConnectionParams, FileNames);
if Assigned(FCmdlineConnectionParams) then begin if Assigned(ConnectionParams) then begin
// Minimal parameter for command line mode is hostname // Minimal parameter for command line mode is hostname
Connected := InitConnection(FCmdlineConnectionParams, True, Connection); InitConnection(ConnectionParams, True, Connection);
end else if AppSettings.ReadBool(asAutoReconnect) then begin end else if AppSettings.ReadBool(asAutoReconnect) then begin
// Auto connection via preference setting // Auto connection via preference setting
// Do not autoconnect if we're in commandline mode and the connection was not successful // Do not autoconnect if we're in commandline mode and the connection was not successful
@ -1692,8 +1686,7 @@ begin
for i:=0 to LastSessions.Count-1 do begin for i:=0 to LastSessions.Count-1 do begin
try try
LoadedParams := TConnectionParameters.Create(LastSessions[i]); LoadedParams := TConnectionParameters.Create(LastSessions[i]);
if InitConnection(LoadedParams, LastActiveSession=LastSessions[i], Connection) then InitConnection(LoadedParams, LastActiveSession=LastSessions[i], Connection);
Connected := True;
except on E:Exception do except on E:Exception do
ErrorDialog(E.Message); ErrorDialog(E.Message);
end; end;
@ -1702,7 +1695,7 @@ begin
end; end;
// Display session manager // Display session manager
if not Connected then begin if Connections.Count = 0 then begin
// Cannot be done in OnCreate because we need ready forms here: // Cannot be done in OnCreate because we need ready forms here:
SessionManager := TConnForm.Create(Self); SessionManager := TConnForm.Create(Self);
DlgResult := mrCancel; DlgResult := mrCancel;
@ -1720,92 +1713,17 @@ begin
end; end;
// Load SQL file(s) by command line // Load SQL file(s) by command line
if not RunQueryFiles(FCmdlineFilenames, nil) then begin if not RunQueryFiles(FileNames, nil) then begin
for i:=0 to FCmdlineFilenames.Count-1 do begin for i:=0 to FileNames.Count-1 do begin
Tab := ActiveOrEmptyQueryTab(False); Tab := ActiveOrEmptyQueryTab(False);
Tab.LoadContents(FCmdlineFilenames[i], True, nil); Tab.LoadContents(FileNames[i], True, nil);
if i = FCmdlineFilenames.Count-1 then if i = FileNames.Count-1 then
SetMainTab(Tab.TabSheet); SetMainTab(Tab.TabSheet);
end; end;
end; end;
end; end;
procedure TMainForm.ParseCommandLineParameters(Parameters: TStringlist);
var
rx: TRegExpr;
AllParams, SessName, Host, User, Pass, Socket: String;
i, Port: Integer;
function GetParamValue(ShortName, LongName: String): String;
begin
Result := '';
rx.Expression := '\s(\-'+ShortName+'|\-\-'+LongName+')\s*\=?\s*([^\-]\S*)';
if rx.Exec(AllParams) then
Result := rx.Match[2];
end;
begin
// Initialize and clear variables
if not Assigned(FCmdlineFilenames) then
FCmdlineFilenames := TStringlist.Create;
FCmdlineFilenames.Clear;
SessName := '';
FreeAndNil(FCmdlineConnectionParams);
// Prepend a space, so the regular expression can request a mandantory space
// before each param name including the first one
AllParams := ' ' + ImplodeStr(' ', Parameters);
rx := TRegExpr.Create;
SessName := GetParamValue('d', 'description');
if SessName <> '' then begin
try
FCmdlineConnectionParams := TConnectionParameters.Create(SessName);
except
on E:Exception do begin
// Session params not found in registry
LogSQL(E.Message);
SessName := '';
end;
end;
end;
// Test if params were passed. If given, override previous values loaded from registry.
// Enables the user to log into a session with a different, non-stored user: -dSession -uSomeOther
Host := GetParamValue('h', 'host');
User := GetParamValue('u', 'user');
Pass := GetParamValue('p', 'password');
Socket := GetParamValue('S', 'socket');
Port := StrToIntDef(GetParamValue('P', 'port'), 0);
// Leave out support for startup script, seems reasonable for command line connecting
if (Host <> '') or (User <> '') or (Pass <> '') or (Port <> 0) or (Socket <> '') then begin
if not Assigned(FCmdlineConnectionParams) then begin
FCmdlineConnectionParams := TConnectionParameters.Create;
FCmdlineConnectionParams.SessionPath := SessName;
end;
if Host <> '' then FCmdlineConnectionParams.Hostname := Host;
if User <> '' then FCmdlineConnectionParams.Username := User;
if Pass <> '' then FCmdlineConnectionParams.Password := Pass;
if Port <> 0 then FCmdlineConnectionParams.Port := Port;
if Socket <> '' then begin
FCmdlineConnectionParams.Hostname := Socket;
FCmdlineConnectionParams.NetType := ntMySQL_NamedPipe;
end;
// Ensure we have a session name to pass to InitConnection
if (FCmdlineConnectionParams.SessionPath = '') and (FCmdlineConnectionParams.Hostname <> '') then
FCmdlineConnectionParams.SessionPath := FCmdlineConnectionParams.Hostname;
end;
// Check for valid filename(s) in parameters
for i:=0 to Parameters.Count-1 do begin
if FileExists(Parameters[i]) then
FCmdlineFilenames.Add(Parameters[i]);
end;
end;
procedure TMainForm.actSessionManagerExecute(Sender: TObject); procedure TMainForm.actSessionManagerExecute(Sender: TObject);
var var
Dialog: TConnForm; Dialog: TConnForm;
@ -10018,18 +9936,20 @@ var
i: Integer; i: Integer;
Connection: TDBConnection; Connection: TDBConnection;
Tab: TQueryTab; Tab: TQueryTab;
ConnectionParams: TConnectionParameters;
FileNames: TStringList;
begin begin
// Probably a second instance is posting its command line parameters here // Probably a second instance is posting its command line parameters here
if (Msg.CopyDataStruct.dwData = SecondInstMsgId) and (SecondInstMsgId <> 0) then begin if (Msg.CopyDataStruct.dwData = SecondInstMsgId) and (SecondInstMsgId <> 0) then begin
ParseCommandLineParameters(ParamBlobToStr(Msg.CopyDataStruct.lpData)); ParseCommandLine(ParamBlobToStr(Msg.CopyDataStruct.lpData), ConnectionParams, FileNames);
if not RunQueryFiles(FCmdlineFilenames, nil) then begin if not RunQueryFiles(FileNames, nil) then begin
for i:=0 to FCmdlineFilenames.Count-1 do begin for i:=0 to FileNames.Count-1 do begin
Tab := ActiveOrEmptyQueryTab(False); Tab := ActiveOrEmptyQueryTab(False);
Tab.LoadContents(FCmdlineFilenames[i], True, nil); Tab.LoadContents(FileNames[i], True, nil);
end; end;
end; end;
if Assigned(FCmdlineConnectionParams) then if Assigned(ConnectionParams) then
InitConnection(FCmdlineConnectionParams, True, Connection); InitConnection(ConnectionParams, True, Connection);
end else end else
// Not the right message id // Not the right message id
inherited; inherited;