From fea0e8e1942ba283e85058c155482fb0f6cde600 Mon Sep 17 00:00:00 2001 From: Ansgar Becker Date: Sun, 16 Sep 2012 16:55:53 +0000 Subject: [PATCH] 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 --- packages/delphiXE/heidisql.dpr | 17 +++-- source/helpers.pas | 96 +++++++++++++++++++------- source/main.pas | 122 ++++++--------------------------- 3 files changed, 106 insertions(+), 129 deletions(-) diff --git a/packages/delphiXE/heidisql.dpr b/packages/delphiXE/heidisql.dpr index 03d32da1..48ff8443 100644 --- a/packages/delphiXE/heidisql.dpr +++ b/packages/delphiXE/heidisql.dpr @@ -47,18 +47,25 @@ uses {$R ..\..\res\updater.RES} 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; SecondInstMsgId := RegisterWindowMessage(APPNAME); - if (not AppSettings.ReadBool(asAllowMultipleInstances)) and CheckForSecondInstance then - Application.Terminate - else begin + if (not AppSettings.ReadBool(asAllowMultipleInstances)) and CheckForSecondInstance then begin + AppSettings.Free; + Application.Terminate; + end else begin Application.Initialize; Application.Title := APPNAME; Application.UpdateFormatSettings := False; Application.CreateForm(TMainForm, MainForm); Application.OnMessage := Mainform.OnMessageHandler; - MainForm.Startup; + MainForm.AfterFormCreate; Application.MainFormOnTaskBar := True; Application.Run; end; diff --git a/source/helpers.pas b/source/helpers.pas index d02488cd..ec7d6bcc 100644 --- a/source/helpers.pas +++ b/source/helpers.pas @@ -267,7 +267,6 @@ type function UnformatNumber(Val: String): String; function FormatNumber( int: Int64; 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=''); function getFirstWord( text: String ): String; function FormatByteNumber( Bytes: Int64; Decimals: Byte = 1 ): String; Overload; @@ -322,11 +321,12 @@ type function ErrorDialog(Msg: string): Integer; overload; function ErrorDialog(const Title, Msg: string): Integer; overload; function GetHTMLCharsetByEncoding(Encoding: TEncoding): String; + procedure ParseCommandLine(Parameters: TStringlist; + var ConnectionParams: TConnectionParameters; var FileNames: TStringList); var AppSettings: TAppSettings; MutexHandle: THandle = 0; - DecimalSeparatorSystemdefault: Char; implementation @@ -933,27 +933,6 @@ begin 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 @@ -2492,6 +2471,77 @@ begin 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 } diff --git a/source/main.pas b/source/main.pas index 30537c42..ff9d0762 100644 --- a/source/main.pas +++ b/source/main.pas @@ -568,7 +568,7 @@ type procedure WMCopyData(var Msg: TWMCopyData); message WM_COPYDATA; procedure FormDestroy(Sender: TObject); procedure FormCreate(Sender: TObject); - procedure Startup; + procedure AfterFormCreate; procedure FormResize(Sender: TObject); procedure actUserManagerExecute(Sender: TObject); procedure actAboutBoxExecute(Sender: TObject); @@ -908,8 +908,6 @@ type FFilterTextDatabase, FFilterTextData: String; FTreeRefreshInProgress: Boolean; - FCmdlineFilenames: TStringlist; - FCmdlineConnectionParams: TConnectionParameters; FSearchReplaceExecuted: Boolean; FDataGridColumnWidthsCustomized: Boolean; FSnippetFilenames: TStringList; @@ -935,7 +933,6 @@ type FCommandStatsQueryCount: Int64; FCommandStatsServerUptime: Integer; - procedure ParseCommandLineParameters(Parameters: TStringlist); procedure SetDelimiter(Value: String); procedure DisplayRowCountStats(Sender: TBaseVirtualTree); procedure insertFunction(Sender: TObject); @@ -1595,16 +1592,15 @@ end; {** Check for connection parameters on commandline or show connections form. } -procedure TMainForm.Startup; +procedure TMainForm.AfterFormCreate; var - CmdlineParameters, LastSessions: TStringlist; + CmdlineParameters, LastSessions, FileNames: TStringlist; Connection: TDBConnection; - LoadedParams: TConnectionParameters; + LoadedParams, ConnectionParams: TConnectionParameters; LastUpdatecheck, LastStatsCall, LastConnect: TDateTime; UpdatecheckInterval, i: Integer; DefaultLastrunDate, LastActiveSession: String; frm : TfrmUpdateCheck; - Connected: Boolean; StatsCall: THttpDownload; SessionPaths: TStringlist; DlgResult: TModalResult; @@ -1668,15 +1664,13 @@ begin end; end; - Connected := False; - CmdlineParameters := TStringList.Create; for i:=1 to ParamCount do CmdlineParameters.Add(ParamStr(i)); - ParseCommandLineParameters(CmdlineParameters); - if Assigned(FCmdlineConnectionParams) then begin + ParseCommandLine(CmdlineParameters, ConnectionParams, FileNames); + if Assigned(ConnectionParams) then begin // 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 // Auto connection via preference setting // 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 try LoadedParams := TConnectionParameters.Create(LastSessions[i]); - if InitConnection(LoadedParams, LastActiveSession=LastSessions[i], Connection) then - Connected := True; + InitConnection(LoadedParams, LastActiveSession=LastSessions[i], Connection); except on E:Exception do ErrorDialog(E.Message); end; @@ -1702,7 +1695,7 @@ begin end; // 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: SessionManager := TConnForm.Create(Self); DlgResult := mrCancel; @@ -1720,92 +1713,17 @@ begin end; // Load SQL file(s) by command line - if not RunQueryFiles(FCmdlineFilenames, nil) then begin - for i:=0 to FCmdlineFilenames.Count-1 do begin + if not RunQueryFiles(FileNames, nil) then begin + for i:=0 to FileNames.Count-1 do begin Tab := ActiveOrEmptyQueryTab(False); - Tab.LoadContents(FCmdlineFilenames[i], True, nil); - if i = FCmdlineFilenames.Count-1 then + Tab.LoadContents(FileNames[i], True, nil); + if i = FileNames.Count-1 then SetMainTab(Tab.TabSheet); 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); var Dialog: TConnForm; @@ -10018,18 +9936,20 @@ var i: Integer; Connection: TDBConnection; Tab: TQueryTab; + ConnectionParams: TConnectionParameters; + FileNames: TStringList; begin // Probably a second instance is posting its command line parameters here if (Msg.CopyDataStruct.dwData = SecondInstMsgId) and (SecondInstMsgId <> 0) then begin - ParseCommandLineParameters(ParamBlobToStr(Msg.CopyDataStruct.lpData)); - if not RunQueryFiles(FCmdlineFilenames, nil) then begin - for i:=0 to FCmdlineFilenames.Count-1 do begin + ParseCommandLine(ParamBlobToStr(Msg.CopyDataStruct.lpData), ConnectionParams, FileNames); + if not RunQueryFiles(FileNames, nil) then begin + for i:=0 to FileNames.Count-1 do begin Tab := ActiveOrEmptyQueryTab(False); - Tab.LoadContents(FCmdlineFilenames[i], True, nil); + Tab.LoadContents(FileNames[i], True, nil); end; end; - if Assigned(FCmdlineConnectionParams) then - InitConnection(FCmdlineConnectionParams, True, Connection); + if Assigned(ConnectionParams) then + InitConnection(ConnectionParams, True, Connection); end else // Not the right message id inherited;