diff --git a/source/connections.dfm b/source/connections.dfm index c8f5bf2f..b549920d 100644 --- a/source/connections.dfm +++ b/source/connections.dfm @@ -4,10 +4,10 @@ object connform: Tconnform Top = 129 BorderIcons = [biSystemMenu] Caption = 'Session manager' - ClientHeight = 319 + ClientHeight = 274 ClientWidth = 494 Color = clBtnFace - Constraints.MinHeight = 355 + Constraints.MinHeight = 310 Constraints.MinWidth = 510 Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText @@ -24,7 +24,7 @@ object connform: Tconnform OnShow = FormShow DesignSize = ( 494 - 319) + 274) PixelsPerInch = 96 TextHeight = 13 object lblSession: TLabel @@ -48,7 +48,7 @@ object connform: Tconnform end object btnSave: TButton Left = 64 - Top = 286 + Top = 241 Width = 50 Height = 25 Anchors = [akLeft, akBottom] @@ -59,7 +59,7 @@ object connform: Tconnform object btnOpen: TButton Tag = 15 Left = 320 - Top = 286 + Top = 241 Width = 80 Height = 25 Anchors = [akRight, akBottom] @@ -72,7 +72,7 @@ object connform: Tconnform object btnCancel: TButton Tag = 16 Left = 406 - Top = 286 + Top = 241 Width = 80 Height = 25 Anchors = [akRight, akBottom] @@ -85,7 +85,7 @@ object connform: Tconnform Left = 9 Top = 27 Width = 162 - Height = 251 + Height = 206 Anchors = [akLeft, akTop, akBottom] EditDelay = 250 Header.AutoSizeIndex = 0 @@ -120,7 +120,7 @@ object connform: Tconnform end object btnNew: TButton Left = 8 - Top = 286 + Top = 241 Width = 50 Height = 25 Anchors = [akLeft, akBottom] @@ -130,7 +130,7 @@ object connform: Tconnform end object btnDelete: TButton Left = 120 - Top = 286 + Top = 241 Width = 50 Height = 25 Anchors = [akLeft, akBottom] @@ -142,14 +142,14 @@ object connform: Tconnform Left = 177 Top = 10 Width = 309 - Height = 270 + Height = 225 Anchors = [akLeft, akTop, akRight, akBottom] Caption = 'Details' TabOrder = 1 Visible = False DesignSize = ( 309 - 270) + 225) object lblHost: TLabel Tag = 6 Left = 8 @@ -186,45 +186,32 @@ object connform: Tconnform Caption = 'Port:' FocusControl = editPort end - object lblOnlyDBs: TLabel - Tag = 13 - Left = 8 - Top = 167 - Width = 63 - Height = 13 - Caption = 'Database(s):' - WordWrap = True - end object lblLastConnectLeft: TLabel Left = 8 - Top = 211 + Top = 167 Width = 65 Height = 13 - Anchors = [akLeft, akBottom] Caption = 'Last connect:' end object lblLastConnectRight: TLabel Left = 99 - Top = 211 + Top = 167 Width = 5 Height = 13 - Anchors = [akLeft, akBottom] Caption = '?' end object lblCreatedLeft: TLabel Left = 8 - Top = 247 + Top = 203 Width = 43 Height = 13 - Anchors = [akLeft, akBottom] Caption = 'Created:' end object lblCreatedRight: TLabel Left = 99 - Top = 247 + Top = 203 Width = 5 Height = 13 - Anchors = [akLeft, akBottom] Caption = '?' end object lblNetworkType: TLabel @@ -236,18 +223,16 @@ object connform: Tconnform end object lblCounterLeft: TLabel Left = 8 - Top = 229 + Top = 185 Width = 43 Height = 13 - Anchors = [akLeft, akBottom] Caption = 'Counter:' end object lblCounterRight: TLabel Left = 99 - Top = 229 + Top = 185 Width = 5 Height = 13 - Anchors = [akLeft, akBottom] Caption = '?' end object editHost: TEdit @@ -318,18 +303,6 @@ object connform: Tconnform TabOrder = 1 OnClick = radioNetTypeClick end - object memoDatabases: TTntMemo - Left = 99 - Top = 164 - Width = 205 - Height = 41 - Anchors = [akLeft, akTop, akRight, akBottom] - Lines.Strings = ( - 'memoDatabases') - ScrollBars = ssVertical - TabOrder = 8 - OnChange = Modification - end object updownPort: TUpDown Left = 159 Top = 117 @@ -344,7 +317,7 @@ object connform: Tconnform object popupSessions: TPopupMenu Images = MainForm.PngImageListMain Left = 176 - Top = 288 + Top = 240 object Save1: TMenuItem Caption = 'Save' ImageIndex = 10 @@ -368,6 +341,6 @@ object connform: Tconnform Interval = 60000 OnTimer = TimerStatisticsTimer Left = 208 - Top = 288 + Top = 240 end end diff --git a/source/connections.pas b/source/connections.pas index 51a41ff6..696b2632 100644 --- a/source/connections.pas +++ b/source/connections.pas @@ -27,7 +27,6 @@ type lblUsername: TLabel; lblPassword: TLabel; lblPort: TLabel; - lblOnlyDBs: TLabel; editHost: TEdit; editUsername: TEdit; editPassword: TEdit; @@ -35,7 +34,6 @@ type chkCompressed: TCheckBox; radioTypeTCPIP: TRadioButton; radioTypeNamedPipe: TRadioButton; - memoDatabases: TTntMemo; updownPort: TUpDown; lblLastConnectLeft: TLabel; lblLastConnectRight: TLabel; @@ -87,7 +85,7 @@ type FSessionNames: TStringlist; FSessionModified, FSessionAdded: Boolean; FOrgNetType: Byte; - FOrgHost, FOrgUser, FOrgPassword, FOrgDatabases: WideString; + FOrgHost, FOrgUser, FOrgPassword: WideString; FOrgCompressed: Boolean; FOrgPort: Integer; function SelectedSession: String; @@ -200,7 +198,6 @@ begin editPort.Text, editUsername.Text, editPassword.Text, - memoDatabases.Text, IntToStr(Integer(chkCompressed.Checked)), SelectedSession) then begin ModalResult := mrOK; @@ -225,7 +222,6 @@ begin else MainReg.WriteInteger(REGNAME_NETTYPE, NETTYPE_NAMEDPIPE); MainReg.WriteBool(REGNAME_COMPRESSED, chkCompressed.Checked); - MainReg.WriteString(REGNAME_ONLYDBS, Utf8Encode(memoDatabases.Text)); if IsNew then MainReg.WriteString(REGNAME_SESSIONCREATED, DateTimeToStr(Now)); FSessionModified := False; @@ -384,7 +380,6 @@ begin FOrgPassword := decrypt(GetRegValue(REGNAME_PASSWORD, '', SelectedSession)); FOrgPort := StrToIntDef(GetRegValue(REGNAME_PORT, '', SelectedSession), DEFAULT_PORT); FOrgCompressed := GetRegValue(REGNAME_COMPRESSED, DEFAULT_COMPRESSED, SelectedSession); - FOrgDatabases := Utf8Decode(GetRegValue(REGNAME_ONLYDBS, '', SelectedSession)); end else begin // Editing a new session, not saved yet FOrgNetType := NETTYPE_TCPIP; @@ -393,7 +388,6 @@ begin FOrgPassword := ''; FOrgPort := DEFAULT_PORT; FOrgCompressed := DEFAULT_COMPRESSED; - FOrgDatabases := ''; end; FLoaded := False; @@ -407,7 +401,6 @@ begin editPassword.Text := FOrgPassword; editPort.Text := IntToStr(FOrgPort); chkCompressed.Checked := FOrgCompressed; - memoDatabases.Text := FOrgDatabases; FLoaded := True; end; @@ -536,7 +529,7 @@ begin else NetType := NETTYPE_NAMEDPIPE; FSessionModified := (FOrgHost <> editHost.Text) or (FOrgUser <> editUsername.Text) or (FOrgPassword <> editPassword.Text) or (FOrgPort <> updownPort.Tag) - or (FOrgCompressed <> chkCompressed.Checked) or (FOrgDatabases <> memoDatabases.Text) + or (FOrgCompressed <> chkCompressed.Checked) or (FOrgNetType <> NetType); ListSessions.Repaint; ValidateControls; diff --git a/source/main.dfm b/source/main.dfm index 4790a634..a6c4c12d 100644 --- a/source/main.dfm +++ b/source/main.dfm @@ -338,59 +338,6 @@ object MainForm: TMainForm Cursor = crSizeWE ResizeStyle = rsUpdate end - object DBtree: TVirtualStringTree - Left = 0 - Top = 0 - Width = 169 - Height = 357 - Align = alLeft - Constraints.MinWidth = 40 - DragMode = dmAutomatic - DragType = dtVCL - Header.AutoSizeIndex = 0 - Header.DefaultHeight = 17 - Header.Font.Charset = DEFAULT_CHARSET - Header.Font.Color = clWindowText - Header.Font.Height = -11 - Header.Font.Name = 'Tahoma' - Header.Font.Style = [] - Header.Options = [hoAutoResize, hoColumnResize, hoDrag] - HintMode = hmTooltip - HotCursor = crHandPoint - Images = PngImageListMain - IncrementalSearch = isInitializedOnly - Indent = 16 - ParentShowHint = False - PopupMenu = popupDB - ShowHint = True - TabOrder = 0 - TreeOptions.AutoOptions = [toAutoDropExpand, toAutoTristateTracking, toAutoDeleteMovedNodes] - TreeOptions.PaintOptions = [toHideFocusRect, toHotTrack, toShowButtons, toShowDropmark, toShowTreeLines, toThemeAware, toUseBlendedImages, toUseExplorerTheme, toHideTreeLinesIfThemed] - TreeOptions.SelectionOptions = [toRightClickSelect] - OnDblClick = DBtreeDblClick - OnExpanded = DBtreeExpanded - OnFocusChanged = DBtreeFocusChanged - OnGetText = DBtreeGetText - OnPaintText = DBtreePaintText - OnGetImageIndex = DBtreeGetImageIndex - OnGetHint = vstGetHint - OnGetNodeDataSize = DBtreeGetNodeDataSize - OnInitChildren = DBtreeInitChildren - OnInitNode = DBtreeInitNode - Columns = < - item - Position = 0 - Width = 110 - WideText = 'Name' - end - item - Alignment = taRightJustify - MinWidth = 0 - Position = 1 - Width = 55 - WideText = 'Size' - end> - end object PageControlMain: TPageControl Left = 173 Top = 0 @@ -1338,6 +1285,98 @@ object MainForm: TMainForm end end end + object pnlLeft: TPanel + Left = 0 + Top = 0 + Width = 169 + Height = 357 + Align = alLeft + BevelOuter = bvNone + TabOrder = 0 + object DBtree: TVirtualStringTree + Left = 0 + Top = 0 + Width = 169 + Height = 336 + Align = alClient + BevelEdges = [beRight] + BevelInner = bvNone + BevelOuter = bvRaised + BevelKind = bkFlat + BorderStyle = bsNone + Constraints.MinWidth = 40 + DragMode = dmAutomatic + DragType = dtVCL + Header.AutoSizeIndex = 0 + Header.DefaultHeight = 17 + Header.Font.Charset = DEFAULT_CHARSET + Header.Font.Color = clWindowText + Header.Font.Height = -11 + Header.Font.Name = 'Tahoma' + Header.Font.Style = [] + Header.Options = [hoAutoResize, hoColumnResize, hoDrag] + HintMode = hmTooltip + HotCursor = crHandPoint + Images = PngImageListMain + IncrementalSearch = isInitializedOnly + Indent = 16 + ParentShowHint = False + PopupMenu = popupDB + RootNodeCount = 1 + ShowHint = True + TabOrder = 0 + TreeOptions.AutoOptions = [toAutoDropExpand, toAutoTristateTracking, toAutoDeleteMovedNodes] + TreeOptions.PaintOptions = [toHideFocusRect, toHotTrack, toShowButtons, toShowDropmark, toShowTreeLines, toThemeAware, toUseBlendedImages, toUseExplorerTheme, toHideTreeLinesIfThemed] + TreeOptions.SelectionOptions = [toRightClickSelect] + OnDblClick = DBtreeDblClick + OnExpanded = DBtreeExpanded + OnFocusChanged = DBtreeFocusChanged + OnGetText = DBtreeGetText + OnPaintText = DBtreePaintText + OnGetImageIndex = DBtreeGetImageIndex + OnGetHint = vstGetHint + OnGetNodeDataSize = DBtreeGetNodeDataSize + OnInitChildren = DBtreeInitChildren + OnInitNode = DBtreeInitNode + Columns = < + item + Position = 0 + Width = 113 + WideText = 'Name' + end + item + Alignment = taRightJustify + MinWidth = 0 + Position = 1 + Width = 55 + WideText = 'Size' + end> + end + object comboOnlyDBs: TTntComboBox + AlignWithMargins = True + Left = 0 + Top = 336 + Width = 169 + Height = 21 + Hint = + 'Database filter|A list of databases, separated by semicolon. Can' + + ' contain regular expressions, e.g. "mydb;test.*;project\d+".' + Margins.Left = 0 + Margins.Top = 0 + Margins.Right = 0 + Margins.Bottom = 0 + Align = alBottom + ItemHeight = 13 + ParentShowHint = False + ShowHint = True + TabOrder = 1 + OnChange = comboOnlyDBsChange + OnDragDrop = comboOnlyDBsDragDrop + OnDragOver = comboOnlyDBsDragOver + OnExit = comboOnlyDBsExit + OnKeyDown = comboOnlyDBsKeyDown + end + end end object ProgressBarStatus: TProgressBar Left = 535 diff --git a/source/main.pas b/source/main.pas index bfd9f575..79d760f6 100644 --- a/source/main.pas +++ b/source/main.pas @@ -219,7 +219,9 @@ type actCopyAsSQL: TAction; CopyAsSQLdata: TMenuItem; panelTop: TPanel; + pnlLeft: TPanel; DBtree: TVirtualStringTree; + comboOnlyDBs: TTntComboBox; Splitter1: TSplitter; PageControlMain: TPageControl; tabData: TTabSheet; @@ -720,6 +722,12 @@ type function IsQueryTab(PageIndex: Integer; IncludeFixed: Boolean): Boolean; procedure popupMainTabsPopup(Sender: TObject); procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean); + procedure comboOnlyDBsChange(Sender: TObject); + procedure comboOnlyDBsExit(Sender: TObject); + procedure comboOnlyDBsDragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; + var Accept: Boolean); + procedure comboOnlyDBsDragDrop(Sender, Source: TObject; X, Y: Integer); + procedure comboOnlyDBsKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); private ReachedEOT : Boolean; FDelimiter: String; @@ -784,7 +792,7 @@ type RoutineEditor: TfrmRoutineEditor; OptionsForm: Toptionsform; SessionManager: TConnForm; - DatabasesWanted, + AllDatabases, Databases : Widestrings.TWideStringList; TemporaryDatabase : WideString; dataselected : Boolean; @@ -837,7 +845,7 @@ type procedure FillPopupQueryLoad; procedure PopupQueryLoadRemoveAbsentFiles( sender: TObject ); procedure SessionConnect(Sender: TObject); - function InitConnection(parNetType: Integer; parHost, parPort, parUser, parPass, parDatabase, parCompress, parSession: WideString): Boolean; + function InitConnection(parNetType: Integer; parHost, parPort, parUser, parPass, parCompress, parSession: WideString): Boolean; //procedure HandleQueryNotification(ASender : TMysqlQuery; AEvent : Integer); function ExecUpdateQuery(sql: WideString; HandleErrors: Boolean = false; DisplayErrors: Boolean = false): Int64; @@ -1176,7 +1184,7 @@ begin MainReg.WriteInteger( REGNAME_QUERYMEMOHEIGHT, pnlQueryMemo.Height ); MainReg.WriteInteger( REGNAME_QUERYHELPERSWIDTH, pnlQueryHelpers.Width ); - MainReg.WriteInteger( REGNAME_DBTREEWIDTH, DBtree.width ); + MainReg.WriteInteger( REGNAME_DBTREEWIDTH, pnlLeft.width ); MainReg.WriteInteger( REGNAME_SQLOUTHEIGHT, SynMemoSQLLog.Height ); // Save width of probably resized columns of all VirtualTrees @@ -1342,7 +1350,7 @@ begin pnlQueryMemo.Height := GetRegValue(REGNAME_QUERYMEMOHEIGHT, pnlQueryMemo.Height); pnlQueryHelpers.Width := GetRegValue(REGNAME_QUERYHELPERSWIDTH, pnlQueryHelpers.Width); - DBtree.Width := GetRegValue(REGNAME_DBTREEWIDTH, DBtree.Width); + pnlLeft.Width := GetRegValue(REGNAME_DBTREEWIDTH, pnlLeft.Width); SynMemoSQLLog.Height := GetRegValue(REGNAME_SQLOUTHEIGHT, SynMemoSQLLog.Height); // Force status bar position to below log memo StatusBar.Top := SynMemoSQLLog.Top + SynMemoSQLLog.Height; @@ -1482,7 +1490,7 @@ procedure TMainForm.Startup; var curParam, parNetType: Byte; sValue, - parHost, parPort, parUser, parPass, parDatabase, + parHost, parPort, parUser, parPass, parCompress, parSession: String; LastUpdatecheck, LastStatsCall, LastConnect: TDateTime; UpdatecheckInterval, i: Integer; @@ -1582,8 +1590,6 @@ begin parUser := sValue else if GetParamValue('p', 'password', curParam, sValue) then parPass := sValue - else if GetParamValue('D', 'database', curParam, sValue) then - parDatabase := sValue else if GetParamValue('d', 'description', curParam, sValue) then parSession := sValue; Inc(curParam); @@ -1597,7 +1603,6 @@ begin parPass := decrypt(GetRegValue(REGNAME_PASSWORD, DEFAULT_PASSWORD, parSession)); parPort := GetRegValue(REGNAME_PORT, IntToStr(DEFAULT_PORT), parSession); parCompress := IntToStr(Integer(GetRegValue(REGNAME_COMPRESSED, DEFAULT_COMPRESSED, parSession))); - parDatabase := GetRegValue(REGNAME_ONLYDBS, '', parSession); end; // Minimal parameter for command line mode is hostname @@ -1605,7 +1610,7 @@ begin if CommandLineMode then begin if parSession = '' then parSession := parHost; - Connected := InitConnection(parNetType, parHost, parPort, parUser, parPass, parDatabase, parCompress, parSession); + Connected := InitConnection(parNetType, parHost, parPort, parUser, parPass, parCompress, parSession); end; // Auto connection via preference setting @@ -1619,7 +1624,6 @@ begin GetRegValue(REGNAME_PORT, '', LastSession), GetRegValue(REGNAME_USER, '', LastSession), decrypt(GetRegValue(REGNAME_PASSWORD, '', LastSession)), - Utf8Decode(GetRegValue(REGNAME_ONLYDBS, '', LastSession)), IntToStr(Integer(GetRegValue(REGNAME_COMPRESSED, DEFAULT_COMPRESSED, LastSession))), LastSession ); @@ -1698,15 +1702,16 @@ begin Mainreg.WriteInteger(REGNAME_SERVERVERSION, mysql_version); Mainreg.WriteString(REGNAME_LASTCONNECT, DateTimeToStr(Now)); - DatabasesWanted := explode(';', FConn.DatabaseList); - DatabasesWanted.Sort; + comboOnlyDBs.Items.Text := Utf8Decode(GetRegValue(REGNAME_ONLYDBS, '', SessionName)); + if comboOnlyDBs.Items.Count > 0 then + comboOnlyDBs.ItemIndex := 0 + else + comboOnlyDBs.Text := ''; + RefreshTree(False); DBTree.Color := GetRegValue(REGNAME_TREEBACKGROUND, clWindow, SessionName); CheckUptime; - // Invoke population of database tree. It's important to do this here after - // having filled DatabasesWanted, not at design time. - DBtree.RootNodeCount := 1; // Define window properties SetWindowConnected( true ); @@ -1795,6 +1800,7 @@ begin // relative from already opened folder! OpenRegistry(SessionName); MainReg.WriteString( REGNAME_LASTUSEDDB, Utf8Encode(ActiveDatabase) ); + MainReg.WriteString( REGNAME_ONLYDBS, Utf8Encode(comboOnlyDBs.Items.Text) ); // Post pending UPDATE if DataGridHasChanges then @@ -1803,10 +1809,8 @@ begin // Clear database and table lists DBtree.ClearSelection; DBtree.FocusedNode := nil; - DBtree.Clear; ClearAllTableLists; - FreeAndNil(DatabasesWanted); - FreeAndNil(Databases); + FreeAndNil(AllDatabases); FreeAndNil(InformationSchemaTables); FreeAndNil(dsShowEngines); FreeAndNil(dsHaveEngines); @@ -1855,13 +1859,12 @@ begin if CreateDatabaseForm.ShowModal = mrOK then begin newdb := CreateDatabaseForm.editDBName.Text; - // Add DB to OnlyDBs-regkey if this is not empty - if DatabasesWanted.Count > 0 then - begin - DatabasesWanted.Add( newdb ); - OpenRegistry(SessionName); - MainReg.WriteString( 'OnlyDBs', ImplodeStr( ';', DatabasesWanted ) ); + // Add new DB to database filter if it's not empty + if comboOnlyDBs.Text <> '' then begin + comboOnlyDBs.Text := comboOnlyDBs.Text + ';' + newdb; + comboOnlyDBs.Items.Insert(0, comboOnlyDBs.Text); end; + FreeAndNil(AllDatabases); // reload db nodes and switch to new one RefreshTree(False, newdb); end; @@ -2450,11 +2453,6 @@ begin try ExecUpdateQuery( 'DROP DATABASE ' + mask(activeDB) ); ClearDbTableList(activeDB); - if DatabasesWanted.IndexOf(activeDB) > -1 then begin - DatabasesWanted.Delete( DatabasesWanted.IndexOf(activeDB) ); - OpenRegistry(SessionName); - MainReg.WriteString( 'OnlyDBs', ImplodeStr( ';', DatabasesWanted ) ); - end; DBtree.Selected[DBtree.GetFirst] := true; RefreshTree(False); finally @@ -2565,7 +2563,7 @@ procedure TMainForm.SessionConnect(Sender: TObject); var Session: String; parNetType: Integer; - parHost, parPort, parUser, parPass, parCompress, parDatabase: WideString; + parHost, parPort, parUser, parPass, parCompress: WideString; begin Session := (Sender as TMenuItem).Caption; parNetType := GetRegValue(REGNAME_NETTYPE, DEFAULT_NETTYPE, Session); @@ -2574,8 +2572,7 @@ begin parPass := decrypt(GetRegValue(REGNAME_PASSWORD, '', Session)); parPort := GetRegValue(REGNAME_PORT, '', Session); parCompress := IntToStr(Integer(GetRegValue(REGNAME_COMPRESSED, DEFAULT_COMPRESSED, Session))); - parDatabase := Utf8Decode(GetRegValue(REGNAME_ONLYDBS, '', Session)); - if InitConnection(parNetType, parHost, parPort, parUser, parPass, parDatabase, parCompress, Session) then + if InitConnection(parNetType, parHost, parPort, parUser, parPass, parCompress, Session) then DoAfterConnect; end; @@ -2584,7 +2581,7 @@ end; Receive connection parameters and create the mdi-window Paremeters are either sent by connection-form or by commandline. } -function TMainform.InitConnection(parNetType: Integer; parHost, parPort, parUser, parPass, parDatabase, parCompress, parSession: WideString): Boolean; +function TMainform.InitConnection(parNetType: Integer; parHost, parPort, parUser, parPass, parCompress, parSession: WideString): Boolean; var MysqlConnection: TMysqlConn; Profile: TOpenConnProf; @@ -2607,7 +2604,6 @@ begin Profile.MysqlParams.PrpDbless := 'true'; Profile.MysqlParams.PrpClientLocalFiles := 'true'; Profile.MysqlParams.PrpClientInteractive := 'true'; - Profile.DatabaseList := parDatabase; MysqlConnection := TMysqlConn.Create(@Profile); @@ -6855,34 +6851,50 @@ procedure TMainForm.DBtreeInitChildren(Sender: TBaseVirtualTree; Node: PVirtualNode; var ChildCount: Cardinal); var ds: TDataset; - specialDbs: WideStrings.TWideStringList; - dbName: WideString; - i: Integer; + i, j: Integer; + DatabasesWanted: TWideStringList; + rx: TRegExpr; begin case Sender.GetNodeLevel(Node) of // Root node has only one single child (user@host) 0: begin Screen.Cursor := crHourglass; - Showstatus( 'Reading Databases...' ); try - Databases := WideStrings.TWideStringList.Create; - if DatabasesWanted.Count = 0 then begin - ds := GetResults( 'SHOW DATABASES' ); - specialDbs := WideStrings.TWideStringList.Create; - for i:=1 to ds.RecordCount do begin - dbName := ds.FieldByName('Database').AsWideString; - if dbName = DBNAME_INFORMATION_SCHEMA then specialDbs.Insert( 0, dbName ) - else Databases.Add( dbName ); - ds.Next; + if not Assigned(AllDatabases) then begin + Showstatus( 'Reading Databases...' ); + AllDatabases := GetCol('SHOW DATABASES'); + end; + if not Assigned(Databases) then + Databases := TWideStringList.Create; + Databases.Clear; + DatabasesWanted := Explode(';', comboOnlyDBs.Text); + if DatabasesWanted.Count > 0 then begin + // Add wanted dbs by comparing strings + for i:=0 to AllDatabases.Count-1 do begin + if DatabasesWanted.IndexOf(AllDatabases[i]) > -1 then + Databases.Add(AllDatabases[i]); end; - ds.Close; - FreeAndNil(ds); - Databases.Sort; - // Prioritised position of system-databases - for i := specialDbs.Count - 1 downto 0 do - Databases.Insert( 0, specialDbs[i] ); - end else for i:=0 to DatabasesWanted.Count-1 do - Databases.Add(DatabasesWanted[i]); + // Add dbs by regular expression, avoiding duplicates + rx := TRegExpr.Create; + for i:=0 to DatabasesWanted.Count-1 do begin + rx.Expression := '^'+DatabasesWanted[i]+'$'; + for j:=0 to AllDatabases.Count-1 do begin + if (Databases.IndexOf(AllDatabases[j]) = -1) and rx.Exec(AllDatabases[j]) then + Databases.Add(AllDatabases[j]); + end; + end; + rx.Free; + end; + FreeAndNil(DatabasesWanted); + if Databases.Count = 0 then + Databases.Assign(AllDatabases); + Databases.Sort; + + // Prioritised position of virtual system database + i := Databases.IndexOf(DBNAME_INFORMATION_SCHEMA); + if i > -1 then + Databases.Move(i, 0); + showstatus( IntToStr( Databases.Count ) + ' Databases', 0 ); ChildCount := Databases.Count; // Avoids excessive InitializeKeywordLists() calls. @@ -7053,9 +7065,11 @@ begin // ReInit tree population DBTree.BeginUpdate; - DBtree.ReinitChildren(DBTree.GetFirst, False); // .ResetNode(DBtree.GetFirst); - if DoResetTableCache then + if DoResetTableCache then begin ClearAllTableLists; + FreeAndNil(AllDatabases); + end; + DBtree.ReinitChildren(DBTree.GetFirst, False); // .ResetNode(DBtree.GetFirst); // Reselect active or new database if present. Could have been deleted or renamed. try if SelectDatabase <> '' then ActiveDatabase := SelectDatabase @@ -9538,5 +9552,75 @@ begin end; end; + +procedure TMainForm.comboOnlyDBsChange(Sender: TObject); +begin + // Immediately apply database filter + RefreshTree(False); +end; + + +procedure TMainForm.comboOnlyDBsExit(Sender: TObject); +var + i: Integer; + FilterText: WideString; +begin + // Add (move) custom filter text to (in) drop down history, if not empty + FilterText := comboOnlyDBs.Text; + if FilterText <> '' then begin + i := comboOnlyDBs.Items.IndexOf(FilterText); + if i > -1 then + comboOnlyDBs.Items.Move(i, 0) + else + comboOnlyDBs.Items.Insert(0, FilterText); + comboOnlyDBs.Text := FilterText; + end; +end; + + +procedure TMainForm.comboOnlyDBsDragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; + var Accept: Boolean); +begin + // DBtree dragging node over DB filter dropdown + Accept := (Source = DBtree) and (DBtree.GetNodeLevel(DBtree.FocusedNode) = 1); +end; + + +procedure TMainForm.comboOnlyDBsDragDrop(Sender, Source: TObject; X, Y: Integer); +var + dbs: TWideStringList; + newdb: WideString; +begin + // DBtree node dropped on DB filter dropdown + dbs := Explode(';', comboOnlyDBs.Text); + newdb := DBtree.Text[DBtree.FocusedNode, DBtree.FocusedColumn]; + if dbs.IndexOf(newdb) = -1 then begin + if (comboOnlyDBs.Text <> '') and (comboOnlyDBs.Text[Length(comboOnlyDBs.Text)-1] <> ';') then + comboOnlyDBs.Text := comboOnlyDBs.Text + ';'; + comboOnlyDBs.Text := comboOnlyDBs.Text + newdb; + comboOnlyDBs.Items.Insert(0, comboOnlyDBs.Text); + comboOnlyDBs.OnChange(Sender); + end; +end; + + +procedure TMainForm.comboOnlyDBsKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); +var + i: Integer; +begin + // Pressing Delete key while filters are dropped down, deletes the filter from the list + i := comboOnlyDBs.ItemIndex; + if comboOnlyDBs.DroppedDown and (Key=VK_DELETE) and (i > -1) then begin + Key := 0; + comboOnlyDBs.Items.Delete(i); + if comboOnlyDBs.Items.Count > i then + comboOnlyDBs.ItemIndex := i + else + comboOnlyDBs.ItemIndex := i-1; + comboOnlyDBs.OnChange(Sender); + end; +end; + + end. diff --git a/source/mysqlquerythread.pas b/source/mysqlquerythread.pas index 37e4b241..7463088d 100644 --- a/source/mysqlquerythread.pas +++ b/source/mysqlquerythread.pas @@ -40,7 +40,6 @@ type // but to keep the name short; this beats "TConnectionProfileDataAndConnectionObject", which I guess would be the proper name. TOpenConnProf = record MysqlParams : TMysqlConnParams; // stuff that needs to be shipped over to the mysql driver. - DatabaseList : WideString; MysqlConn : TZConnection; end; POpenConnProf = ^TOpenConnProf;