Experimental: Reintroduce table tab, this time by placing the existing editors for tables, views and routines as TFrames onto that tab. Unfortunately a whole bunch of GUI changes involved here which makes the diff unreadable. Should solve issue #1149 .

This commit is contained in:
Ansgar Becker
2009-06-04 12:56:55 +00:00
parent 0bed55de02
commit f01893d08a
16 changed files with 614 additions and 675 deletions

View File

@ -106,10 +106,6 @@ const
REGNAME_SQLHELPWINHEIGHT = 'SQLHelp_WindowHeight'; REGNAME_SQLHELPWINHEIGHT = 'SQLHelp_WindowHeight';
REGNAME_SQLHELPPLWIDTH = 'SQLHelp_PnlLeftWidth'; REGNAME_SQLHELPPLWIDTH = 'SQLHelp_PnlLeftWidth';
REGNAME_SQLHELPPRHEIGHT = 'SQLHelp_PnlRightTopHeight'; REGNAME_SQLHELPPRHEIGHT = 'SQLHelp_PnlRightTopHeight';
REGNAME_PROCEDITOR_WIDTH = 'ProcedureEditorWidth';
REGNAME_PROCEDITOR_HEIGHT = 'ProcedureEditorHeight';
REGNAME_TABLEEDITOR_WIDTH = 'TableEditorWidth';
REGNAME_TABLEEDITOR_HEIGHT = 'TableEditorHeight';
REGNAME_TABLEEDITOR_TABSHEIGHT = 'TableEditorTabsHeight'; REGNAME_TABLEEDITOR_TABSHEIGHT = 'TableEditorTabsHeight';
REGNAME_HOST = 'Host'; REGNAME_HOST = 'Host';
DEFAULT_HOST = '127.0.0.1'; DEFAULT_HOST = '127.0.0.1';
@ -164,10 +160,6 @@ const
REGNAME_LAST_UPDATECHECK = 'UpdatecheckLastrun'; REGNAME_LAST_UPDATECHECK = 'UpdatecheckLastrun';
REGNAME_MAINTWINWIDTH = 'Maintenance_WindowWidth'; REGNAME_MAINTWINWIDTH = 'Maintenance_WindowWidth';
REGNAME_MAINTWINHEIGHT = 'Maintenance_WindowHeight'; REGNAME_MAINTWINHEIGHT = 'Maintenance_WindowHeight';
REGNAME_VIEWWINWIDTH = 'View_WindowWidth';
REGNAME_VIEWWINHEIGHT = 'View_WindowHeight';
REGNAME_CRTABLEWINWIDTH = 'CreateTable_WindowWidth';
REGNAME_CRTABLEWINHEIGHT = 'CreateTable_WindowHeight';
REGNAME_USERMNGR_WINWIDTH = 'Usermanager_WindowWidth'; REGNAME_USERMNGR_WINWIDTH = 'Usermanager_WindowWidth';
REGNAME_USERMNGR_WINHEIGHT = 'Usermanager_WindowHeight'; REGNAME_USERMNGR_WINHEIGHT = 'Usermanager_WindowHeight';
REGNAME_SELECTDBO_WINWIDTH = 'SelectDBO_WindowWidth'; REGNAME_SELECTDBO_WINWIDTH = 'SelectDBO_WindowWidth';
@ -262,16 +254,6 @@ const
TXT_ASC = 'ASC'; // Used for caption of "Direction"-button TXT_ASC = 'ASC'; // Used for caption of "Direction"-button
TXT_DESC = 'DESC'; // dito TXT_DESC = 'DESC'; // dito
// Node types of Virtual Tree nodes
NODETYPE_DEFAULT = 0;
NODETYPE_DB = 1;
NODETYPE_TABLE = 2;
NODETYPE_CRASHED_TABLE = 3;
NODETYPE_VIEW = 4;
NODETYPE_FUNCTION = 5;
NODETYPE_PROCEDURE = 6;
NODETYPE_COLUMN = 7;
// Data grid: How many bytes to fetch from data fields that are potentially large. // Data grid: How many bytes to fetch from data fields that are potentially large.
GRIDMAXDATA: Integer = 256; GRIDMAXDATA: Integer = 256;

View File

@ -349,7 +349,7 @@ begin
checkListTables.Items.Clear; checkListTables.Items.Clear;
ds := Mainform.FetchDbTableList(comboSelectDatabase.Text); ds := Mainform.FetchDbTableList(comboSelectDatabase.Text);
while not ds.Eof do begin while not ds.Eof do begin
if GetDBObjectType(ds.Fields) = NODETYPE_TABLE then if GetDBObjectType(ds.Fields) = lntTable then
checkListTables.Items.Add(ds.FieldByName(DBO_NAME).AsWideString); checkListTables.Items.Add(ds.FieldByName(DBO_NAME).AsWideString);
ds.Next; ds.Next;
end; end;

View File

@ -15,11 +15,17 @@ uses Classes, SysUtils, Graphics, db, clipbrd, dialogs,
type type
TListNodeType = (lntNone, lntDb, lntTable, lntCrashedTable, lntView, lntFunction, lntProcedure, lntColumn);
TListNode = record
Text: WideString;
NodeType: TListNodeType;
end;
// Define a record which can hold everything we need for one row / node in a VirtualStringTree // Define a record which can hold everything we need for one row / node in a VirtualStringTree
TVTreeData = record TVTreeData = record
Captions: TWideStringList; Captions: TWideStringList;
ImageIndex: Integer; ImageIndex: Integer;
NodeType: Byte; NodeType: TListNodeType;
end; end;
PVTreedata = ^TVTreeData; PVTreedata = ^TVTreeData;
@ -160,11 +166,11 @@ type
function FormatByteNumber( Bytes: String; Decimals: Byte = 1 ): String; Overload; function FormatByteNumber( Bytes: String; Decimals: Byte = 1 ): String; Overload;
function FormatTimeNumber( Seconds: Cardinal ): String; function FormatTimeNumber( Seconds: Cardinal ): String;
function TColorToHex( Color : TColor ): string; function TColorToHex( Color : TColor ): string;
function GetVTCaptions( VT: TVirtualStringTree; OnlySelected: Boolean = False; Column: Integer = 0; OnlyNodeType: Integer = NODETYPE_DEFAULT ): TWideStringList; function GetVTCaptions( VT: TVirtualStringTree; OnlySelected: Boolean = False; Column: Integer = 0; OnlyNodeType: TListNodeType = lntNone ): TWideStringList;
procedure SetVTSelection( VT: TVirtualStringTree; Selected: TWideStringList ); procedure SetVTSelection( VT: TVirtualStringTree; Selected: TWideStringList );
function Pos2(const Needle, HayStack: string; const StartPos: Integer) : Integer; function Pos2(const Needle, HayStack: string; const StartPos: Integer) : Integer;
function GetTempDir: String; function GetTempDir: String;
function GetDBObjectType( TableStatus: TFields ): Byte; function GetDBObjectType( TableStatus: TFields ): TListNodeType;
procedure SetWindowSizeGrip(hWnd: HWND; Enable: boolean); procedure SetWindowSizeGrip(hWnd: HWND; Enable: boolean);
procedure SaveUnicodeFile(Filename: String; Text: WideString); procedure SaveUnicodeFile(Filename: String; Text: WideString);
function CreateUnicodeFileStream(Filename: String): TFileStream; function CreateUnicodeFileStream(Filename: String): TFileStream;
@ -2217,7 +2223,7 @@ end;
Return a TStringList with captions from all selected nodes in a VirtualTree Return a TStringList with captions from all selected nodes in a VirtualTree
Especially helpful when toMultiSelect is True Especially helpful when toMultiSelect is True
} }
function GetVTCaptions( VT: TVirtualStringTree; OnlySelected: Boolean = False; Column: Integer = 0; OnlyNodeType: Integer = NODETYPE_DEFAULT ): TWideStringList; function GetVTCaptions( VT: TVirtualStringTree; OnlySelected: Boolean = False; Column: Integer = 0; OnlyNodeType: TListNodeType = lntNone ): TWideStringList;
var var
SelectedNodes : TNodeArray; SelectedNodes : TNodeArray;
NodeData: PVTreeData; NodeData: PVTreeData;
@ -2232,7 +2238,7 @@ begin
for i := 0 to Length(SelectedNodes) - 1 do for i := 0 to Length(SelectedNodes) - 1 do
begin begin
NodeData := VT.GetNodeData( SelectedNodes[i] ); NodeData := VT.GetNodeData( SelectedNodes[i] );
if (OnlyNodeType = NODETYPE_DEFAULT) // Add all nodes, regardless of their types if (OnlyNodeType = lntNone) // Add all nodes, regardless of their types
or (NodeData.NodeType = OnlyNodeType) then // Node in loop is of specified type or (NodeData.NodeType = OnlyNodeType) then // Node in loop is of specified type
Result.Add( NodeData.Captions[Column] ); Result.Add( NodeData.Captions[Column] );
end; end;
@ -2241,7 +2247,7 @@ begin
// Fetch all nodes // Fetch all nodes
a := Mainform.GetVTreeDataArray( VT )^; a := Mainform.GetVTreeDataArray( VT )^;
for i := 0 to High(a) do begin for i := 0 to High(a) do begin
if (OnlyNodeType = NODETYPE_DEFAULT) if (OnlyNodeType = lntNone)
or (a[i].NodeType = OnlyNodeType) then or (a[i].NodeType = OnlyNodeType) then
Result.Add( a[i].Captions[ Column ] ); Result.Add( a[i].Captions[ Column ] );
end; end;
@ -2296,7 +2302,7 @@ end;
// Tell type of db object (table|view) by a given row from a SHOW TABLE STATUS result // Tell type of db object (table|view) by a given row from a SHOW TABLE STATUS result
function GetDBObjectType( TableStatus: TFields ): Byte; function GetDBObjectType( TableStatus: TFields ): TListNodeType;
var var
t: String; t: String;
begin begin
@ -2308,28 +2314,28 @@ begin
but for views which is missing its tables, it says but for views which is missing its tables, it says
"Views bla references invalid..." "Views bla references invalid..."
} }
Result := NODETYPE_TABLE; Result := lntTable;
if TableStatus.FindField('Type') <> nil then begin if TableStatus.FindField('Type') <> nil then begin
t := TableStatus.FindField('Type').AsString; t := TableStatus.FindField('Type').AsString;
if t = 'BASE TABLE' then if t = 'BASE TABLE' then
Result := NODETYPE_TABLE Result := lntTable
else if t = 'VIEW' then else if t = 'VIEW' then
Result := NODETYPE_VIEW Result := lntView
else if t = 'FUNCTION' then else if t = 'FUNCTION' then
Result := NODETYPE_FUNCTION Result := lntFunction
else if t = 'PROCEDURE' then else if t = 'PROCEDURE' then
Result := NODETYPE_PROCEDURE; Result := lntProcedure;
end else begin end else begin
if if
TableStatus[1].IsNull and // Engine column is NULL for views TableStatus[1].IsNull and // Engine column is NULL for views
TableStatus[2].IsNull and TableStatus[2].IsNull and
(Pos('VIEW', UpperCase(TableStatus.FieldByName(DBO_COMMENT).AsWideString)) > 0) (Pos('VIEW', UpperCase(TableStatus.FieldByName(DBO_COMMENT).AsWideString)) > 0)
then Result := NODETYPE_VIEW; then Result := lntView;
if if
TableStatus[1].IsNull and TableStatus[1].IsNull and
TableStatus[2].IsNull and TableStatus[2].IsNull and
(Pos('MARKED AS CRASHED', UpperCase(TableStatus.FieldByName(DBO_COMMENT).AsWideString)) > 0) (Pos('MARKED AS CRASHED', UpperCase(TableStatus.FieldByName(DBO_COMMENT).AsWideString)) > 0)
then Result := NODETYPE_CRASHED_TABLE; then Result := lntCrashedTable;
end; end;
end; end;

View File

@ -111,7 +111,7 @@ begin
ComboBoxTables.Items.Clear; ComboBoxTables.Items.Clear;
ds := Mainform.FetchDbTableList(ComboBoxDBs.Text); ds := Mainform.FetchDbTableList(ComboBoxDBs.Text);
while not ds.Eof do begin while not ds.Eof do begin
if GetDBObjectType(ds.Fields) in [NODETYPE_TABLE, NODETYPE_VIEW] then if GetDBObjectType(ds.Fields) in [lntTable, lntView] then
ComboBoxTables.Items.Add(ds.FieldByName(DBO_NAME).AsString); ComboBoxTables.Items.Add(ds.FieldByName(DBO_NAME).AsString);
ds.Next; ds.Next;
end; end;

View File

@ -146,10 +146,10 @@ begin
// read tables from db // read tables from db
comboTable.Items.Clear; comboTable.Items.Clear;
seldb := Mainform.ActiveDatabase; seldb := Mainform.ActiveDatabase;
seltable := Mainform.SelectedTable; seltable := Mainform.SelectedTable.Text;
ds := Mainform.FetchDbTableList(comboDatabase.Text); ds := Mainform.FetchDbTableList(comboDatabase.Text);
while not ds.Eof do begin while not ds.Eof do begin
if GetDBObjectType(ds.Fields) in [NODETYPE_TABLE, NODETYPE_VIEW] then if GetDBObjectType(ds.Fields) in [lntTable, lntView] then
comboTable.Items.Add(ds.FieldByName(DBO_NAME).AsWideString); comboTable.Items.Add(ds.FieldByName(DBO_NAME).AsWideString);
count := comboTable.Items.Count-1; count := comboTable.Items.Count-1;
if (comboDatabase.Text = seldb) and (comboTable.Items[count] = seltable) then if (comboDatabase.Text = seldb) and (comboTable.Items[count] = seltable) then

View File

@ -362,9 +362,9 @@ object MainForm: TMainForm
TreeOptions.AutoOptions = [toAutoDropExpand, toAutoTristateTracking, toAutoDeleteMovedNodes] TreeOptions.AutoOptions = [toAutoDropExpand, toAutoTristateTracking, toAutoDeleteMovedNodes]
TreeOptions.PaintOptions = [toHideFocusRect, toHotTrack, toShowButtons, toShowDropmark, toShowTreeLines, toThemeAware, toUseBlendedImages, toUseExplorerTheme, toHideTreeLinesIfThemed] TreeOptions.PaintOptions = [toHideFocusRect, toHotTrack, toShowButtons, toShowDropmark, toShowTreeLines, toThemeAware, toUseBlendedImages, toUseExplorerTheme, toHideTreeLinesIfThemed]
TreeOptions.SelectionOptions = [toRightClickSelect] TreeOptions.SelectionOptions = [toRightClickSelect]
OnChange = DBtreeChange
OnDblClick = DBtreeDblClick OnDblClick = DBtreeDblClick
OnExpanded = DBtreeExpanded OnExpanded = DBtreeExpanded
OnFocusChanged = DBtreeFocusChanged
OnGetText = DBtreeGetText OnGetText = DBtreeGetText
OnPaintText = DBtreePaintText OnPaintText = DBtreePaintText
OnGetImageIndex = DBtreeGetImageIndex OnGetImageIndex = DBtreeGetImageIndex
@ -917,6 +917,10 @@ object MainForm: TMainForm
end> end>
end end
end end
object tabEditor: TTabSheet
Caption = 'Table'
ImageIndex = 14
end
object tabData: TTabSheet object tabData: TTabSheet
Caption = 'Data' Caption = 'Data'
ImageIndex = 41 ImageIndex = 41
@ -2122,13 +2126,6 @@ object MainForm: TMainForm
ImageIndex = 119 ImageIndex = 119
OnExecute = actCreateRoutineExecute OnExecute = actCreateRoutineExecute
end end
object actViewData: TAction
Category = 'Data'
Caption = 'Data ...'
Hint = 'Displays data grid and allows row editing'
ImageIndex = 41
OnExecute = actViewDataExecute
end
object actEditObject: TAction object actEditObject: TAction
Category = 'Database' Category = 'Database'
Caption = 'Edit' Caption = 'Edit'
@ -5850,12 +5847,6 @@ object MainForm: TMainForm
OnPopup = popupDBPopup OnPopup = popupDBPopup
Left = 136 Left = 136
Top = 64 Top = 64
object menuViewData: TMenuItem
Action = actViewData
end
object N16: TMenuItem
Caption = '-'
end
object menuEditObject: TMenuItem object menuEditObject: TMenuItem
Action = actEditObject Action = actEditObject
ShortCut = 32781 ShortCut = 32781

View File

@ -405,20 +405,18 @@ type
btnExit: TToolButton; btnExit: TToolButton;
lblSorryNoData: TLabel; lblSorryNoData: TLabel;
menuPrint: TMenuItem; menuPrint: TMenuItem;
N16: TMenuItem;
menuEditObject: TMenuItem; menuEditObject: TMenuItem;
menuCreateObject: TMenuItem; menuCreateObject: TMenuItem;
menuDeleteObject: TMenuItem; menuDeleteObject: TMenuItem;
menuMaintenance2: TMenuItem; menuMaintenance2: TMenuItem;
menuEmptyTables: TMenuItem; menuEmptyTables: TMenuItem;
actViewData: TAction;
menuViewData: TMenuItem;
actEditObject: TAction; actEditObject: TAction;
menuCreateDB: TMenuItem; menuCreateDB: TMenuItem;
menuCreateTable: TMenuItem; menuCreateTable: TMenuItem;
menuCreateTableCopy: TMenuItem; menuCreateTableCopy: TMenuItem;
menuCreateView: TMenuItem; menuCreateView: TMenuItem;
menuCreateRoutine: TMenuItem; menuCreateRoutine: TMenuItem;
tabEditor: TTabSheet;
procedure refreshMonitorConfig; procedure refreshMonitorConfig;
procedure loadWindowConfig; procedure loadWindowConfig;
procedure saveWindowConfig; procedure saveWindowConfig;
@ -609,7 +607,8 @@ type
PVirtualNode; Column: TColumnIndex; var Result: Integer); PVirtualNode; Column: TColumnIndex; var Result: Integer);
procedure vstHeaderDraggedOut(Sender: TVTHeader; Column: TColumnIndex; procedure vstHeaderDraggedOut(Sender: TVTHeader; Column: TColumnIndex;
DropPosition: TPoint); DropPosition: TPoint);
procedure DBtreeChange(Sender: TBaseVirtualTree; Node: PVirtualNode); procedure DBtreeFocusChanged(Sender: TBaseVirtualTree; Node: PVirtualNode;
Column: TColumnIndex);
procedure DBtreeDblClick(Sender: TObject); procedure DBtreeDblClick(Sender: TObject);
procedure DBtreeGetImageIndex(Sender: TBaseVirtualTree; Node: PVirtualNode; procedure DBtreeGetImageIndex(Sender: TBaseVirtualTree; Node: PVirtualNode;
Kind: TVTImageKind; Column: TColumnIndex; var Ghosted: Boolean; var Kind: TVTImageKind; Column: TColumnIndex; var Ghosted: Boolean; var
@ -678,7 +677,6 @@ type
Column: TColumnIndex; var Allowed: Boolean); Column: TColumnIndex; var Allowed: Boolean);
procedure DBtreeExpanded(Sender: TBaseVirtualTree; Node: PVirtualNode); procedure DBtreeExpanded(Sender: TBaseVirtualTree; Node: PVirtualNode);
procedure actEditObjectExecute(Sender: TObject); procedure actEditObjectExecute(Sender: TObject);
procedure actViewDataExecute(Sender: TObject);
procedure ListTablesDblClick(Sender: TObject); procedure ListTablesDblClick(Sender: TObject);
private private
ReachedEOT : Boolean; ReachedEOT : Boolean;
@ -722,24 +720,25 @@ type
procedure DisplayRowCountStats(MatchingRows: Int64 = -1); procedure DisplayRowCountStats(MatchingRows: Int64 = -1);
procedure insertFunction(Sender: TObject); procedure insertFunction(Sender: TObject);
function GetActiveDatabase: WideString; function GetActiveDatabase: WideString;
function GetSelectedTable: WideString; function GetSelectedTable: TListNode;
procedure SetSelectedDatabase(db: WideString); procedure SetSelectedDatabase(db: WideString);
procedure SetSelectedTable(table: WideString); procedure SelectDBObject(Text: WideString; NodeType: TListNodeType);
procedure SetVisibleListColumns( List: TVirtualStringTree; Columns: WideStrings.TWideStringList ); procedure SetVisibleListColumns( List: TVirtualStringTree; Columns: WideStrings.TWideStringList );
function GetTableSize(ds: TDataSet): Int64; function GetTableSize(ds: TDataSet): Int64;
procedure ToggleFilterPanel(ForceVisible: Boolean = False); procedure ToggleFilterPanel(ForceVisible: Boolean = False);
function GetSelTableColumns: TDataset; function GetSelTableColumns: TDataset;
function GetSelTableKeys: TDataset; function GetSelTableKeys: TDataset;
procedure AutoCalcColWidths(Tree: TVirtualStringTree; PrevLayout: Widestrings.TWideStringlist = nil); procedure AutoCalcColWidths(Tree: TVirtualStringTree; PrevLayout: Widestrings.TWideStringlist = nil);
procedure PlaceObjectEditor(Which: TListNodeType);
public public
cancelling: Boolean; cancelling: Boolean;
virtualDesktopName: string; virtualDesktopName: string;
MaintenanceForm: TOptimize; MaintenanceForm: TOptimize;
ViewForm: TfrmView; ViewEditor: TfrmView;
UserManagerForm: TUserManagerForm; UserManagerForm: TUserManagerForm;
SelectDBObjectForm: TfrmSelectDBObject; SelectDBObjectForm: TfrmSelectDBObject;
SQLHelpForm: TfrmSQLhelp; SQLHelpForm: TfrmSQLhelp;
RoutineEditForm: TfrmRoutineEditor; RoutineEditor: TfrmRoutineEditor;
OptionsForm: Toptionsform; OptionsForm: Toptionsform;
DatabasesWanted, DatabasesWanted,
Databases : Widestrings.TWideStringList; Databases : Widestrings.TWideStringList;
@ -786,7 +785,7 @@ type
prefNullColorDefault, prefNullColorDefault,
prefNullBG : TColor; prefNullBG : TColor;
CreateDatabaseForm : TCreateDatabaseForm; CreateDatabaseForm : TCreateDatabaseForm;
TableEditorForm : TfrmTableEditor; TableEditor : TfrmTableEditor;
FDataGridResult, FDataGridResult,
FQueryGridResult : TGridResult; FQueryGridResult : TGridResult;
FDataGridSelect : WideStrings.TWideStringList; FDataGridSelect : WideStrings.TWideStringList;
@ -819,7 +818,7 @@ type
property Conn : TOpenConnProf read FConn; property Conn : TOpenConnProf read FConn;
property ActiveDatabase : WideString read GetActiveDatabase write SetSelectedDatabase; property ActiveDatabase : WideString read GetActiveDatabase write SetSelectedDatabase;
property SelectedTable : WideString read GetSelectedTable write SetSelectedTable; property SelectedTable : TListNode read GetSelectedTable;
function FetchActiveDbTableList: TDataSet; function FetchActiveDbTableList: TDataSet;
function RefreshActiveDbTableList: TDataSet; function RefreshActiveDbTableList: TDataSet;
@ -835,8 +834,8 @@ type
procedure DeactivateFileLogging; procedure DeactivateFileLogging;
procedure TrimSQLLog; procedure TrimSQLLog;
procedure TableEnginesCombo(var Combobox: TCombobox); procedure TableEnginesCombo(var Combobox: TCombobox);
function GetNodeType(Node: PVirtualNode): Byte; function GetNodeType(Node: PVirtualNode): TListNodeType;
function GetSelectedNodeType: Byte; function GetSelectedNodeType: TListNodeType;
procedure RefreshTree(DoResetTableCache: Boolean; SelectDatabase: WideString = ''); procedure RefreshTree(DoResetTableCache: Boolean; SelectDatabase: WideString = '');
procedure RefreshTreeDB(db: WideString); procedure RefreshTreeDB(db: WideString);
function FindDBNode(db: WideString): PVirtualNode; function FindDBNode(db: WideString): PVirtualNode;
@ -861,6 +860,7 @@ type
procedure SaveListSetup( List: TVirtualStringTree ); procedure SaveListSetup( List: TVirtualStringTree );
procedure RestoreListSetup( List: TVirtualStringTree ); procedure RestoreListSetup( List: TVirtualStringTree );
function GetCollations(Items: TStrings = nil): TDataset; function GetCollations(Items: TStrings = nil): TDataset;
procedure SetEditorTabCaption(Editor: TFrame; ObjName: WideString);
end; end;
@ -1137,10 +1137,10 @@ begin
SaveListSetup(ListCommandStats); SaveListSetup(ListCommandStats);
SaveListSetup(ListTables); SaveListSetup(ListTables);
FreeAndNil(RoutineEditForm); FreeAndNil(RoutineEditor);
FreeAndNil(MaintenanceForm); FreeAndNil(MaintenanceForm);
FreeAndNil(UserManagerForm); FreeAndNil(UserManagerForm);
FreeAndNil(ViewForm); FreeAndNil(ViewEditor);
FreeAndNil(SelectDBObjectForm); FreeAndNil(SelectDBObjectForm);
FreeAndNil(SQLHelpForm); FreeAndNil(SQLHelpForm);
FreeAndNil(OptionsForm); FreeAndNil(OptionsForm);
@ -1696,7 +1696,7 @@ begin
FreeAndNil(dsCollations); FreeAndNil(dsCollations);
// Free forms which use session based datasets, fx dsShowEngines // Free forms which use session based datasets, fx dsShowEngines
FreeAndNil(TableEditorForm); FreeAndNil(TableEditor);
FreeAndNil(CreateDatabaseForm); FreeAndNil(CreateDatabaseForm);
// Closing connection // Closing connection
@ -1869,10 +1869,10 @@ end;
} }
procedure TMainForm.actCreateViewExecute(Sender: TObject); procedure TMainForm.actCreateViewExecute(Sender: TObject);
begin begin
if ViewForm = nil then tabEditor.TabVisible := True;
ViewForm := TfrmView.Create(Self); PagecontrolMain.ActivePage := tabEditor;
ViewForm.EditViewName := ''; PlaceObjectEditor(lntView);
ViewForm.ShowModal; ViewEditor.Init;
end; end;
@ -2080,7 +2080,7 @@ begin
// Copy data in focused grid as HTML table // Copy data in focused grid as HTML table
Screen.Cursor := crHourglass; Screen.Cursor := crHourglass;
S := TMemoryStream.Create; S := TMemoryStream.Create;
if ActiveGrid = DataGrid then Title := SelectedTable if ActiveGrid = DataGrid then Title := SelectedTable.Text
else Title := 'SQL query'; else Title := 'SQL query';
try try
GridData := ActiveData; GridData := ActiveData;
@ -2104,7 +2104,7 @@ begin
// Copy data in focused grid as XML // Copy data in focused grid as XML
Screen.Cursor := crHourglass; Screen.Cursor := crHourglass;
S := TMemoryStream.Create; S := TMemoryStream.Create;
if ActiveGrid = DataGrid then Root := SelectedTable if ActiveGrid = DataGrid then Root := SelectedTable.Text
else Root := 'SQL query'; else Root := 'SQL query';
try try
GridData := ActiveData; GridData := ActiveData;
@ -2128,7 +2128,7 @@ begin
// Copy data in focused grid as SQL // Copy data in focused grid as SQL
Screen.Cursor := crHourglass; Screen.Cursor := crHourglass;
S := TMemoryStream.Create; S := TMemoryStream.Create;
if ActiveGrid = DataGrid then Tablename := SelectedTable if ActiveGrid = DataGrid then Tablename := SelectedTable.Text
else Tablename := 'unknown'; else Tablename := 'unknown';
try try
GridData := ActiveData; GridData := ActiveData;
@ -2157,7 +2157,7 @@ begin
Grid := ActiveGrid; Grid := ActiveGrid;
GridData := ActiveData; GridData := ActiveData;
if Grid = DataGrid then if Grid = DataGrid then
Title := SelectedTable Title := SelectedTable.Text
else else
Title := 'SQL query'; Title := 'SQL query';
@ -2259,10 +2259,10 @@ begin
InDBTree := TPopupMenu((Comp as TMenuItem).GetParentMenu).PopupComponent = DBTree; InDBTree := TPopupMenu((Comp as TMenuItem).GetParentMenu).PopupComponent = DBTree;
if InDBTree then begin if InDBTree then begin
// If a table is selected, use that for preselection. If only a db was selected, use all tables inside it. // If a table is selected, use that for preselection. If only a db was selected, use all tables inside it.
if SelectedTable <> '' then if SelectedTable.Text <> '' then
f.SelectedTables.Add(Mainform.SelectedTable) f.SelectedTables.Add(SelectedTable.Text)
else if Mainform.ActiveDatabase <> '' then begin else if Mainform.ActiveDatabase <> '' then begin
ds := Mainform.FetchDbTableList(Mainform.ActiveDatabase); ds := Mainform.FetchDbTableList(ActiveDatabase);
while not ds.Eof do begin while not ds.Eof do begin
f.SelectedTables.Add(ds.FieldByName(DBO_NAME).AsWideString); f.SelectedTables.Add(ds.FieldByName(DBO_NAME).AsWideString);
ds.Next; ds.Next;
@ -2323,7 +2323,7 @@ begin
if InDBTree then begin if InDBTree then begin
// drop table selected in tree view. // drop table selected in tree view.
case GetSelectedNodeType of case GetSelectedNodeType of
NODETYPE_DB: begin lntDb: begin
if MessageDlg('Drop Database "'+activeDB+'"?' + crlf + crlf + 'WARNING: You will lose all tables in database '+activeDB+'!', mtConfirmation, [mbok,mbcancel], 0) <> mrok then if MessageDlg('Drop Database "'+activeDB+'"?' + crlf + crlf + 'WARNING: You will lose all tables in database '+activeDB+'!', mtConfirmation, [mbok,mbcancel], 0) <> mrok then
Abort; Abort;
Screen.Cursor := crHourglass; Screen.Cursor := crHourglass;
@ -2342,18 +2342,18 @@ begin
end; end;
Exit; Exit;
end; end;
NODETYPE_TABLE, NODETYPE_CRASHED_TABLE: Tables.Add(SelectedTable); lntTable, lntCrashedTable: Tables.Add(SelectedTable.Text);
NODETYPE_VIEW: Views.Add(SelectedTable); lntView: Views.Add(SelectedTable.Text);
NODETYPE_PROCEDURE: Procedures.Add(SelectedTable); lntProcedure: Procedures.Add(SelectedTable.Text);
NODETYPE_FUNCTION: Functions.Add(SelectedTable); lntFunction: Functions.Add(SelectedTable.Text);
end; end;
end else begin end else begin
// Invoked from database tab // Invoked from database tab
Tables := GetVTCaptions(ListTables, True, 0, NODETYPE_TABLE); Tables := GetVTCaptions(ListTables, True, 0, lntTable);
Tables.AddStrings(GetVTCaptions(ListTables, True, 0, NODETYPE_CRASHED_TABLE)); Tables.AddStrings(GetVTCaptions(ListTables, True, 0, lntCrashedTable));
Views := GetVTCaptions(ListTables, True, 0, NODETYPE_VIEW); Views := GetVTCaptions(ListTables, True, 0, lntView);
Procedures := GetVTCaptions(ListTables, True, 0, NODETYPE_PROCEDURE); Procedures := GetVTCaptions(ListTables, True, 0, lntProcedure);
Functions := GetVTCaptions(ListTables, True, 0, NODETYPE_FUNCTION); Functions := GetVTCaptions(ListTables, True, 0, lntFunction);
end; end;
// Fix actions temporarily enabled for popup menu. // Fix actions temporarily enabled for popup menu.
@ -2551,9 +2551,10 @@ end;
procedure TMainForm.actCreateTableExecute(Sender: TObject); procedure TMainForm.actCreateTableExecute(Sender: TObject);
begin begin
if TableEditorForm = nil then tabEditor.TabVisible := True;
TableEditorForm := TfrmTableEditor.Create(Self); PagecontrolMain.ActivePage := tabEditor;
TableEditorForm.ShowModal; PlaceObjectEditor(lntTable);
TableEditor.Init;
end; end;
@ -3285,6 +3286,7 @@ begin
) then PageControlMain.ActivePage := tabHost; ) then PageControlMain.ActivePage := tabHost;
tabDatabase.TabVisible := false; tabDatabase.TabVisible := false;
tabEditor.TabVisible := false;
tabData.TabVisible := false; tabData.TabVisible := false;
Caption := winName; Caption := winName;
@ -3300,6 +3302,7 @@ begin
) then PageControlMain.ActivePage := tabDatabase; ) then PageControlMain.ActivePage := tabDatabase;
tabDatabase.TabVisible := true; tabDatabase.TabVisible := true;
tabEditor.TabVisible := false;
tabData.TabVisible := false; tabData.TabVisible := false;
Caption := winName + ' - /' + db; Caption := winName + ' - /' + db;
@ -3425,16 +3428,14 @@ begin
if DataGridHasChanges then if DataGridHasChanges then
actDataPostChangesExecute(Sender); actDataPostChangesExecute(Sender);
// Ensure <Data> is visible
tabData.TabVisible := true;
// Switch to <Data> // Switch to <Data>
PageControlMain.ActivePage := tabData; PageControlMain.ActivePage := tabData;
try try
if (SelectedTable <> '') and (ActiveDatabase <> '') then begin if (SelectedTable.Text <> '') and (ActiveDatabase <> '') then begin
if FDataGridSelect = nil then if FDataGridSelect = nil then
FDataGridSelect := WideStrings.TWideStringlist.Create; FDataGridSelect := WideStrings.TWideStringlist.Create;
if DataGridTable <> SelectedTable then begin if DataGridTable <> SelectedTable.Text then begin
FDataGridSelect.Clear; FDataGridSelect.Clear;
FSelectedTableColumns := nil; FSelectedTableColumns := nil;
FSelectedTableKeys := nil; FSelectedTableKeys := nil;
@ -3447,7 +3448,7 @@ begin
// Disable default if crash indicator on current table is found // Disable default if crash indicator on current table is found
if MainReg.ValueExists(REGPREFIX_CRASH_IN_DATA) then begin if MainReg.ValueExists(REGPREFIX_CRASH_IN_DATA) then begin
MainReg.DeleteValue(REGNAME_DEFAULTVIEW); MainReg.DeleteValue(REGNAME_DEFAULTVIEW);
LogSQL('A crash in the previous data loading for this table ('+SelectedTable+') was detected. Filtering was automatically reset to avoid the same crash for now.'); LogSQL('A crash in the previous data loading for this table ('+SelectedTable.Text+') was detected. Filtering was automatically reset to avoid the same crash for now.');
// Reset crash indicator. // Reset crash indicator.
MainReg.DeleteValue(REGPREFIX_CRASH_IN_DATA); MainReg.DeleteValue(REGPREFIX_CRASH_IN_DATA);
end else begin end else begin
@ -3535,7 +3536,7 @@ begin
select_base := copy( select_base, 1, Length(select_base)-1 ); select_base := copy( select_base, 1, Length(select_base)-1 );
select_base_full := copy( select_base_full, 1, Length(select_base_full)-1 ); select_base_full := copy( select_base_full, 1, Length(select_base_full)-1 );
// Include db name for cases in which dbtree is switching databases and pending updates are in process // Include db name for cases in which dbtree is switching databases and pending updates are in process
select_from := ' FROM '+mask(ActiveDatabase)+'.'+mask(SelectedTable); select_from := ' FROM '+mask(ActiveDatabase)+'.'+mask(SelectedTable.Text);
// Final SELECT segments // Final SELECT segments
DataGridCurrentSelect := select_base; DataGridCurrentSelect := select_base;
@ -3571,7 +3572,7 @@ begin
debug('mem: browse row initialization complete.'); debug('mem: browse row initialization complete.');
// Switched to another table // Switched to another table
if DataGridTable <> SelectedTable then begin if DataGridTable <> SelectedTable.Text then begin
DataGrid.OffsetXY := Point(0, 0); // Scroll to top left DataGrid.OffsetXY := Point(0, 0); // Scroll to top left
FreeAndNil(PrevTableColWidths); // Throw away remembered, manually resized column widths FreeAndNil(PrevTableColWidths); // Throw away remembered, manually resized column widths
end; end;
@ -3583,14 +3584,14 @@ begin
DataGrid.Header.Columns.EndUpdate; DataGrid.Header.Columns.EndUpdate;
DataGrid.EndUpdate; DataGrid.EndUpdate;
FreeAndNil(sl_query); FreeAndNil(sl_query);
if DataGridTable = SelectedTable then if DataGridTable = SelectedTable.Text then
DataGrid.OffsetXY := OldOffsetXY; DataGrid.OffsetXY := OldOffsetXY;
viewingdata := false; viewingdata := false;
EnumerateRecentFilters; EnumerateRecentFilters;
Screen.Cursor := crDefault; Screen.Cursor := crDefault;
end; end;
DataGridDB := ActiveDatabase; DataGridDB := ActiveDatabase;
DataGridTable := SelectedTable; DataGridTable := SelectedTable.Text;
AutoCalcColWidths(DataGrid, PrevTableColWidths); AutoCalcColWidths(DataGrid, PrevTableColWidths);
end; end;
@ -3607,16 +3608,16 @@ var
i: Integer; i: Integer;
s: WideString; s: WideString;
begin begin
lblDataTop.Caption := ActiveDatabase + '.' + SelectedTable; lblDataTop.Caption := ActiveDatabase + '.' + SelectedTable.Text;
IsFiltered := self.DataGridCurrentFilter <> ''; IsFiltered := self.DataGridCurrentFilter <> '';
if GetSelectedNodeType = NODETYPE_TABLE then begin if GetSelectedNodeType = lntTable then begin
// Get rowcount from table // Get rowcount from table
ds := FetchActiveDbTableList; ds := FetchActiveDbTableList;
rows_total := -1; rows_total := -1;
IsInnodb := False; IsInnodb := False;
for i := 0 to ds.RecordCount - 1 do begin for i := 0 to ds.RecordCount - 1 do begin
if ds.FieldByName(DBO_NAME).AsWideString = SelectedTable then begin if ds.FieldByName(DBO_NAME).AsWideString = SelectedTable.Text then begin
s := ds.FieldByName(DBO_ROWS).AsString; s := ds.FieldByName(DBO_ROWS).AsString;
if s <> '' then rows_total := MakeInt(s); if s <> '' then rows_total := MakeInt(s);
IsInnodb := ds.Fields[1].AsString = 'InnoDB'; IsInnodb := ds.Fields[1].AsString = 'InnoDB';
@ -3957,21 +3958,21 @@ begin
VTRowDataListTables[i-1].NodeType := GetDBObjectType( ds.Fields); VTRowDataListTables[i-1].NodeType := GetDBObjectType( ds.Fields);
// Find icon // Find icon
case VTRowDataListTables[i-1].NodeType of case VTRowDataListTables[i-1].NodeType of
NODETYPE_TABLE, NODETYPE_CRASHED_TABLE: // A normal table lntTable, lntCrashedTable: // A normal table
begin begin
if GetDBObjectType(ds.Fields) = NODETYPE_CRASHED_TABLE then if GetDBObjectType(ds.Fields) = lntCrashedTable then
VTRowDataListTables[i-1].ImageIndex := ICONINDEX_CRASHED_TABLE VTRowDataListTables[i-1].ImageIndex := ICONINDEX_CRASHED_TABLE
else else
VTRowDataListTables[i-1].ImageIndex := ICONINDEX_TABLE; VTRowDataListTables[i-1].ImageIndex := ICONINDEX_TABLE;
end; end;
NODETYPE_VIEW: lntView:
VTRowDataListTables[i-1].ImageIndex := ICONINDEX_VIEW; VTRowDataListTables[i-1].ImageIndex := ICONINDEX_VIEW;
NODETYPE_PROCEDURE: lntProcedure:
VTRowDataListTables[i-1].ImageIndex := ICONINDEX_STOREDPROCEDURE; VTRowDataListTables[i-1].ImageIndex := ICONINDEX_STOREDPROCEDURE;
NODETYPE_FUNCTION: lntFunction:
VTRowDataListTables[i-1].ImageIndex := ICONINDEX_STOREDFUNCTION; VTRowDataListTables[i-1].ImageIndex := ICONINDEX_STOREDFUNCTION;
end; end;
@ -4396,11 +4397,11 @@ const
if Fields.FindField(DBO_TYPE) <> nil then if Fields.FindField(DBO_TYPE) <> nil then
ObjType := LowerCase(Fields.FieldByName(DBO_TYPE).AsString); ObjType := LowerCase(Fields.FieldByName(DBO_TYPE).AsString);
case GetDBObjectType(Fields) of case GetDBObjectType(Fields) of
NODETYPE_TABLE: Icon := ICONINDEX_TABLE; lntTable: Icon := ICONINDEX_TABLE;
NODETYPE_CRASHED_TABLE: Icon := ICONINDEX_CRASHED_TABLE; lntCrashedTable: Icon := ICONINDEX_CRASHED_TABLE;
NODETYPE_FUNCTION: Icon := ICONINDEX_STOREDFUNCTION; lntFunction: Icon := ICONINDEX_STOREDFUNCTION;
NODETYPE_PROCEDURE: Icon := ICONINDEX_STOREDPROCEDURE; lntProcedure: Icon := ICONINDEX_STOREDPROCEDURE;
NODETYPE_VIEW: Icon := ICONINDEX_VIEW; lntView: Icon := ICONINDEX_VIEW;
else Icon := -1; else Icon := -1;
end; end;
SynCompletionProposal1.InsertList.Add( ObjName ); SynCompletionProposal1.InsertList.Add( ObjName );
@ -4610,7 +4611,7 @@ var
begin begin
// Tables and views can be renamed, routines cannot // Tables and views can be renamed, routines cannot
NodeData := Sender.GetNodeData(Node); NodeData := Sender.GetNodeData(Node);
Allowed := NodeData.NodeType in [NODETYPE_TABLE, NODETYPE_VIEW]; Allowed := NodeData.NodeType in [lntTable, lntView];
end; end;
@ -4678,15 +4679,6 @@ begin
end; end;
procedure TMainForm.actViewDataExecute(Sender: TObject);
begin
if Assigned(ListTables.FocusedNode) then begin
SelectedTable := ListTables.Text[ListTables.FocusedNode, ListTables.FocusedColumn];
PageControlMain.ActivePage := tabData;
end;
end;
{** {**
Column-title clicked -> generate "ORDER BY" Column-title clicked -> generate "ORDER BY"
} }
@ -4956,8 +4948,8 @@ begin
actCreateView.Enabled := L in [1,2]; actCreateView.Enabled := L in [1,2];
actCreateRoutine.Enabled := L in [1,2]; actCreateRoutine.Enabled := L in [1,2];
actDropObjects.Enabled := L in [1,2]; actDropObjects.Enabled := L in [1,2];
actCopyTable.Enabled := HasFocus and (GetSelectedNodeType in [NODETYPE_TABLE, NODETYPE_CRASHED_TABLE, NODETYPE_VIEW]); actCopyTable.Enabled := HasFocus and (GetSelectedNodeType in [lntTable, lntCrashedTable, lntView]);
actEmptyTables.Enabled := HasFocus and (GetSelectedNodeType in [NODETYPE_TABLE, NODETYPE_CRASHED_TABLE, NODETYPE_VIEW]); actEmptyTables.Enabled := HasFocus and (GetSelectedNodeType in [lntTable, lntCrashedTable, lntView]);
actEditObject.Enabled := L > 0; actEditObject.Enabled := L > 0;
// Show certain items which are valid only here // Show certain items which are valid only here
actViewData.Visible := False; actViewData.Visible := False;
@ -4975,7 +4967,7 @@ begin
actEmptyTables.Enabled := False; actEmptyTables.Enabled := False;
if HasFocus then begin if HasFocus then begin
NodeData := ListTables.GetNodeData(ListTables.FocusedNode); NodeData := ListTables.GetNodeData(ListTables.FocusedNode);
actEmptyTables.Enabled := NodeData.NodeType in [NODETYPE_TABLE, NODETYPE_CRASHED_TABLE, NODETYPE_VIEW]; actEmptyTables.Enabled := NodeData.NodeType in [lntTable, lntCrashedTable, lntView];
end; end;
actEditObject.Enabled := HasFocus; actEditObject.Enabled := HasFocus;
// Show certain items which are valid only here // Show certain items which are valid only here
@ -5515,23 +5507,25 @@ begin
end; end;
function TMainForm.GetSelectedTable: WideString; function TMainForm.GetSelectedTable: TListNode;
begin begin
if DBtree.GetFirstSelected = nil then Result := '' if Assigned(DBtree.FocusedNode) and (DBtree.GetNodeLevel(DBtree.FocusedNode)=2) then begin
else case DBtree.GetNodeLevel(DBtree.GetFirstSelected) of Result.Text := DBtree.Text[DBtree.FocusedNode, 0];
2: Result := DBtree.Text[DBtree.GetFirstSelected, 0]; Result.NodeType := GetSelectedNodeType;
else Result := ''; end else begin
Result.Text := '';
Result.NodeType := lntNone;
end; end;
end; end;
function TMainForm.GetNodeType(Node: PVirtualNode): Byte; function TMainForm.GetNodeType(Node: PVirtualNode): TListNodeType;
var var
ds: TDataset; ds: TDataset;
begin begin
Result := NODETYPE_DEFAULT; Result := lntNone;
if Assigned(Node) then case DBtree.GetNodeLevel(Node) of if Assigned(Node) then case DBtree.GetNodeLevel(Node) of
1: Result := NODETYPE_DB; 1: Result := lntDb;
2: begin 2: begin
ds := FetchDbTableList(DBTree.Text[Node.Parent, 0]); ds := FetchDbTableList(DBTree.Text[Node.Parent, 0]);
ds.RecNo := Node.Index+1; ds.RecNo := Node.Index+1;
@ -5540,17 +5534,18 @@ begin
end; end;
end; end;
function TMainForm.GetSelectedNodeType: Byte; function TMainForm.GetSelectedNodeType: TListNodeType;
begin begin
Result := GetNodeType(DBtree.GetFirstSelected); Result := GetNodeType(DBtree.GetFirstSelected);
end; end;
procedure TMainForm.SetSelectedTable(table: WideString); procedure TMainForm.SelectDBObject(Text: WideString; NodeType: TListNodeType);
var var
i: integer; i: integer;
dbnode, tnode, snode: PVirtualNode; dbnode, tnode, snode: PVirtualNode;
begin begin
debug('SelectDBObject()');
// Detect db node // Detect db node
case DBtree.GetNodeLevel( DBtree.GetFirstSelected ) of case DBtree.GetNodeLevel( DBtree.GetFirstSelected ) of
1: dbnode := DBtree.GetFirstSelected; 1: dbnode := DBtree.GetFirstSelected;
@ -5562,7 +5557,7 @@ begin
tnode := DBtree.GetFirstChild(dbnode); tnode := DBtree.GetFirstChild(dbnode);
for i := 0 to dbnode.ChildCount - 1 do begin for i := 0 to dbnode.ChildCount - 1 do begin
// Select table node if it has the wanted caption // Select table node if it has the wanted caption
if DBtree.Text[tnode, 0] = table then begin if (DBtree.Text[tnode, 0] = Text) and (GetNodeType(tnode) = NodeType) then begin
snode := tnode; snode := tnode;
break; break;
end; end;
@ -5573,7 +5568,7 @@ begin
tnode := DBtree.GetFirstChild(dbnode); tnode := DBtree.GetFirstChild(dbnode);
for i := 0 to dbnode.ChildCount - 1 do begin for i := 0 to dbnode.ChildCount - 1 do begin
// Select table node if it has the wanted caption // Select table node if it has the wanted caption
if AnsiCompareText(DBtree.Text[tnode, 0], table) = 0 then begin if (AnsiCompareText(DBtree.Text[tnode, 0], Text) = 0) and (GetNodeType(tnode) = NodeType) then begin
snode := tnode; snode := tnode;
break; break;
end; end;
@ -5585,9 +5580,11 @@ begin
DBTree.ScrollIntoView(snode, False); DBTree.ScrollIntoView(snode, False);
DBtree.Expanded[dbnode] := True; DBtree.Expanded[dbnode] := True;
DBtree.Selected[snode] := True; DBtree.Selected[snode] := True;
// Implicitely calls OnFocusChanged:
DBTree.FocusedNode := snode;
exit; exit;
end; end;
raise Exception.Create('Table node ' + table + ' not found in tree.'); raise Exception.Create('Table node ' + Text + ' not found in tree.');
end; end;
@ -5664,7 +5661,7 @@ begin
begin begin
// Keep native order of columns // Keep native order of columns
lboxQueryHelpers.Sorted := False; lboxQueryHelpers.Sorted := False;
if SelectedTable <> '' then begin if SelectedTable.Text <> '' then begin
FSelectedTableColumns.First; FSelectedTableColumns.First;
while not FSelectedTableColumns.Eof do begin while not FSelectedTableColumns.Eof do begin
lboxQueryHelpers.Items.Add(FSelectedTableColumns.Fields[0].AsWideString); lboxQueryHelpers.Items.Add(FSelectedTableColumns.Fields[0].AsWideString);
@ -6172,13 +6169,15 @@ var
Value : WideString; Value : WideString;
ValueList : WideStrings.TWideStringList; ValueList : WideStrings.TWideStringList;
Regname: String; Regname: String;
frm: TCustomForm;
begin begin
ValueList := WideStrings.TWideStringList.Create; ValueList := WideStrings.TWideStringList.Create;
// Column widths // Column widths
Regname := List.Name; Regname := List.Name;
if GetParentForm(List) <> Self then frm := GetParentForm(List);
Regname := GetParentForm(List).Name + '.' + Regname; if (frm <> Self) and (Assigned(frm)) then
Regname := frm.Name + '.' + Regname;
Value := GetRegValue(REGPREFIX_COLWIDTHS + Regname, ''); Value := GetRegValue(REGPREFIX_COLWIDTHS + Regname, '');
if Value <> '' then begin if Value <> '' then begin
ValueList := Explode( ',', Value ); ValueList := Explode( ',', Value );
@ -6634,7 +6633,7 @@ begin
end; end;
1: case GetNodeType(Node) of 1: case GetNodeType(Node) of
// Calculate and display the sum of all table sizes in ALL dbs if all table lists are cached // Calculate and display the sum of all table sizes in ALL dbs if all table lists are cached
NODETYPE_DEFAULT: begin lntNone: begin
AllListsCached := true; AllListsCached := true;
for i := 0 to Databases.Count - 1 do begin for i := 0 to Databases.Count - 1 do begin
if not DbTableListCachedAndValid(Databases[i]) then begin if not DbTableListCachedAndValid(Databases[i]) then begin
@ -6658,7 +6657,7 @@ begin
else CellText := ''; else CellText := '';
end; end;
// Calculate and display the sum of all table sizes in ONE db, if the list is already cached. // Calculate and display the sum of all table sizes in ONE db, if the list is already cached.
NODETYPE_DB: begin lntDb: begin
db := DBtree.Text[Node, 0]; db := DBtree.Text[Node, 0];
if not DbTableListCachedAndValid(db) then if not DbTableListCachedAndValid(db) then
CellText := '' CellText := ''
@ -6676,7 +6675,7 @@ begin
else CellText := ''; else CellText := '';
end; end;
end; end;
NODETYPE_TABLE: begin lntTable: begin
db := DBtree.Text[Node.Parent, 0]; db := DBtree.Text[Node.Parent, 0];
ds := FetchDbTableList(db); ds := FetchDbTableList(db);
ds.RecNo := Node.Index + 1; ds.RecNo := Node.Index + 1;
@ -6709,21 +6708,21 @@ begin
ds := FetchDbTableList(Databases[Node.Parent.Index]); ds := FetchDbTableList(Databases[Node.Parent.Index]);
ds.RecNo := Node.Index+1; ds.RecNo := Node.Index+1;
case GetDBObjectType(ds.Fields) of case GetDBObjectType(ds.Fields) of
NODETYPE_TABLE: lntTable:
if Kind = ikSelected then if Kind = ikSelected then
ImageIndex := ICONINDEX_TABLE_HIGHLIGHT ImageIndex := ICONINDEX_TABLE_HIGHLIGHT
else ImageIndex := ICONINDEX_TABLE; else ImageIndex := ICONINDEX_TABLE;
NODETYPE_VIEW: lntView:
if Kind = ikSelected then if Kind = ikSelected then
ImageIndex := ICONINDEX_VIEW_HIGHLIGHT ImageIndex := ICONINDEX_VIEW_HIGHLIGHT
else ImageIndex := ICONINDEX_VIEW; else ImageIndex := ICONINDEX_VIEW;
NODETYPE_CRASHED_TABLE: lntCrashedTable:
if Kind = ikSelected then if Kind = ikSelected then
ImageIndex := ICONINDEX_CRASHED_TABLE_HIGHLIGHT ImageIndex := ICONINDEX_CRASHED_TABLE_HIGHLIGHT
else ImageIndex := ICONINDEX_CRASHED_TABLE; else ImageIndex := ICONINDEX_CRASHED_TABLE;
NODETYPE_PROCEDURE: lntProcedure:
ImageIndex := ICONINDEX_STOREDPROCEDURE; ImageIndex := ICONINDEX_STOREDPROCEDURE;
NODETYPE_FUNCTION: lntFunction:
ImageIndex := ICONINDEX_STOREDFUNCTION; ImageIndex := ICONINDEX_STOREDFUNCTION;
end; end;
end; end;
@ -6823,10 +6822,12 @@ end;
{** {**
Selection in database tree has changed Selection in database tree has changed
} }
procedure TMainForm.DBtreeChange(Sender: TBaseVirtualTree; Node: PVirtualNode); procedure TMainForm.DBtreeFocusChanged(Sender: TBaseVirtualTree;
Node: PVirtualNode; Column: TColumnIndex);
var var
newDb: WideString; newDb: WideString;
begin begin
debug('DBtreeFocusChanged()');
if not Assigned(Node) then if not Assigned(Node) then
Exit; Exit;
// Post pending UPDATE // Post pending UPDATE
@ -6840,13 +6841,15 @@ begin
end; end;
2: begin 2: begin
newDb := Databases[Node.Parent.Index]; newDb := Databases[Node.Parent.Index];
lblSorryNoData.Visible := False; tabEditor.TabVisible := True;
if GetSelectedNodeType = NODETYPE_PROCEDURE then lblSorryNoData.Visible := True; tabData.TabVisible := SelectedTable.NodeType in [lntTable, lntCrashedTable, lntView];
if GetSelectedNodeType = NODETYPE_FUNCTION then lblSorryNoData.Visible := True; if tabEditor.TabVisible then begin
dataselected := false; actEditObjectExecute(Sender);
PageControlMain.ActivePage := tabData; if (PagecontrolMain.ActivePage <> tabEditor) and (PagecontrolMain.ActivePage <> tabData) then
viewdata(self); PagecontrolMain.ActivePage := tabEditor
PageControlMainChange(Self); else if PagecontrolMain.ActivePage = tabData then
ViewData(Sender);
end;
end; end;
end; end;
if newDb <> '' then if newDb <> '' then
@ -6888,7 +6891,8 @@ end;
} }
procedure TMainForm.RefreshTree(DoResetTableCache: Boolean; SelectDatabase: WideString = ''); procedure TMainForm.RefreshTree(DoResetTableCache: Boolean; SelectDatabase: WideString = '');
var var
oldActiveDatabase, oldSelectedTable, db: WideString; oldActiveDatabase, db: WideString;
oldSelectedTable: TListNode;
Node: PVirtualNode; Node: PVirtualNode;
ExpandedDBs, TablesFetched: WideStrings.TWideStringList; ExpandedDBs, TablesFetched: WideStrings.TWideStringList;
i: Integer; i: Integer;
@ -6938,7 +6942,7 @@ begin
TablesFetched.Free; TablesFetched.Free;
try try
if oldSelectedTable <> '' then SelectedTable := oldSelectedTable; if oldSelectedTable.Text <> '' then SelectDBObject(oldSelectedTable.Text, oldSelectedTable.NodeType);
except except
end; end;
DBTree.EndUpdate; DBTree.EndUpdate;
@ -7191,7 +7195,7 @@ begin
// Set indicator for possibly crashing query // Set indicator for possibly crashing query
OpenRegistry(SessionName); OpenRegistry(SessionName);
regCrashIndicName := Utf8Encode(REGPREFIX_CRASH_IN_DATA + ActiveDatabase + '.' + SelectedTable); regCrashIndicName := Utf8Encode(REGPREFIX_CRASH_IN_DATA + ActiveDatabase + '.' + SelectedTable.Text);
MainReg.WriteBool(regCrashIndicName, True); MainReg.WriteBool(regCrashIndicName, True);
// start query // start query
@ -7807,7 +7811,7 @@ var
msg: String; msg: String;
begin begin
Node := Sender.GetFirstSelected; Node := Sender.GetFirstSelected;
sql := 'DELETE FROM '+mask(SelectedTable)+' WHERE'; sql := 'DELETE FROM '+mask(SelectedTable.Text)+' WHERE';
while Assigned(Node) do begin while Assigned(Node) do begin
EnsureChunkLoaded(Sender, Node); EnsureChunkLoaded(Sender, Node);
sql := sql + ' (' + sql := sql + ' (' +
@ -7928,7 +7932,7 @@ begin
if CheckUniqueKeyClause then begin if CheckUniqueKeyClause then begin
sql := sql :=
'SELECT ' + mask(Col.Name) + 'SELECT ' + mask(Col.Name) +
' FROM ' + mask(SelectedTable) + ' FROM ' + mask(SelectedTable.Text) +
' WHERE ' + GetWhereClause(Row, @Data.Columns) ' WHERE ' + GetWhereClause(Row, @Data.Columns)
; ;
ds := GetResults(sql); ds := GetResults(sql);
@ -8016,9 +8020,9 @@ begin
if (FLastSelectedTableColumns = nil) or (FLastSelectedTableColumns.State = dsInactive) then begin if (FLastSelectedTableColumns = nil) or (FLastSelectedTableColumns.State = dsInactive) then begin
FreeAndNil(FLastSelectedTableColumns); FreeAndNil(FLastSelectedTableColumns);
// Avoid SQL error on routines // Avoid SQL error on routines
if GetSelectedNodeType in [NODETYPE_TABLE, NODETYPE_VIEW] then begin if GetSelectedNodeType in [lntTable, lntView] then begin
ShowStatus('Reading table columns ...'); ShowStatus('Reading table columns ...');
FLastSelectedTableColumns := GetResults( 'SHOW /*!32332 FULL */ COLUMNS FROM ' + mask(SelectedTable), false ); FLastSelectedTableColumns := GetResults( 'SHOW /*!32332 FULL */ COLUMNS FROM ' + mask(SelectedTable.Text), false );
end; end;
end; end;
Result := FLastSelectedTableColumns; Result := FLastSelectedTableColumns;
@ -8029,9 +8033,9 @@ begin
if (FLastSelectedTableKeys = nil) or (FLastSelectedTableKeys.State = dsInactive) then begin if (FLastSelectedTableKeys = nil) or (FLastSelectedTableKeys.State = dsInactive) then begin
FreeAndNil(FLastSelectedTableKeys); FreeAndNil(FLastSelectedTableKeys);
// Avoid SQL error on routines // Avoid SQL error on routines
if GetSelectedNodeType in [NODETYPE_TABLE, NODETYPE_VIEW] then begin if GetSelectedNodeType in [lntTable, lntView] then begin
ShowStatus('Reading table keys ...'); ShowStatus('Reading table keys ...');
FLastSelectedTableKeys := GetResults( 'SHOW KEYS FROM ' + mask(SelectedTable) ); FLastSelectedTableKeys := GetResults( 'SHOW KEYS FROM ' + mask(SelectedTable.Text) );
end; end;
end; end;
Result := FLastSelectedTableKeys; Result := FLastSelectedTableKeys;
@ -8298,7 +8302,7 @@ function TMainForm.GetRegKeyTable: String;
begin begin
// Return the slightly complex registry path to \Servers\ThisServer\curdb|curtable // Return the slightly complex registry path to \Servers\ThisServer\curdb|curtable
Result := REGPATH + REGKEY_SESSIONS + SessionName + '\' + Result := REGPATH + REGKEY_SESSIONS + SessionName + '\' +
Utf8Encode(ActiveDatabase) + REGDELIM + Utf8Encode(SelectedTable); Utf8Encode(ActiveDatabase) + REGDELIM + Utf8Encode(SelectedTable.Text);
end; end;
@ -8756,9 +8760,10 @@ end;
procedure TMainForm.actCreateRoutineExecute(Sender: TObject); procedure TMainForm.actCreateRoutineExecute(Sender: TObject);
begin begin
if not Assigned(RoutineEditForm) then tabEditor.TabVisible := True;
RoutineEditForm := TfrmRoutineEditor.Create(Self); PagecontrolMain.ActivePage := tabEditor;
RoutineEditForm.ShowModal; PlaceObjectEditor(lntProcedure);
RoutineEditor.Init;
end; end;
@ -8838,56 +8843,101 @@ begin
end; end;
procedure TMainForm.PlaceObjectEditor(Which: TListNodeType);
var
frm: TFrame;
begin
// Place the relevant editor frame onto the editor tab, hide all others
if (not (Which in [lntTable, lntCrashedTable])) and Assigned(TableEditor) then
FreeAndNil(TableEditor);
if (Which <> lntView) and Assigned(ViewEditor) then
FreeAndNil(ViewEditor);
if (not (Which in [lntProcedure, lntFunction])) and Assigned(RoutineEditor) then
FreeAndNil(RoutineEditor);
if Which in [lntTable, lntCrashedTable] then begin
if not Assigned(TableEditor) then
TableEditor := TfrmTableEditor.Create(tabEditor);
frm := TableEditor;
end else if Which = lntView then begin
if not Assigned(ViewEditor) then
ViewEditor := TfrmView.Create(tabEditor);
frm := ViewEditor;
end else if Which in [lntProcedure, lntFunction] then begin
if not Assigned(RoutineEditor) then
RoutineEditor := TfrmRoutineEditor.Create(tabEditor);
frm := RoutineEditor;
end else
Exit;
frm.Parent := tabEditor;
end;
procedure TMainForm.SetEditorTabCaption(Editor: TFrame; ObjName: WideString);
var
ObjType, Cap: WideString;
IconIndex: Integer;
begin
if Editor = TableEditor then begin
ObjType := 'Table';
IconIndex := ICONINDEX_TABLE;
end else if Editor = ViewEditor then begin
ObjType := 'View';
IconIndex := ICONINDEX_VIEW;
end else if Editor = RoutineEditor then begin
ObjType := 'Routine';
IconIndex := ICONINDEX_STOREDPROCEDURE;
end else
Exit;
tabEditor.ImageIndex := IconIndex;
Cap := ObjType+': ';
if ObjName = '' then
Cap := Cap + '[Untitled]'
else
Cap := sstr(Cap + ObjName, 30);
tabEditor.Caption := Cap;
end;
procedure TMainForm.actEditObjectExecute(Sender: TObject); procedure TMainForm.actEditObjectExecute(Sender: TObject);
var var
Act: TAction;
InDBTree: Boolean;
ObjectType: Byte;
ObjectName: WideString;
NodeData: PVTreeData; NodeData: PVTreeData;
RoutineType: String;
begin begin
Act := Sender as TAction; debug('actEditObjectExecute()');
InDBTree := (Act.ActionComponent is TMenuItem) if ListTables.Focused then begin
and (TPopupMenu((Act.ActionComponent as TMenuItem).GetParentMenu).PopupComponent = DBTree); // Got here from ListTables.OnDblClick or ListTables's context menu item "Edit"
if InDBTree then begin
ObjectType := GetSelectedNodeType;
ObjectName := DBTree.Text[DBTree.FocusedNode, DBTree.FocusedColumn];
end else begin
NodeData := ListTables.GetNodeData(ListTables.FocusedNode); NodeData := ListTables.GetNodeData(ListTables.FocusedNode);
ObjectType := NodeData.NodeType; if (NodeData.Captions[0] <> SelectedTable.Text) or (NodeData.NodeType <> SelectedTable.NodeType) then
ObjectName := ListTables.Text[ListTables.FocusedNode, ListTables.FocusedColumn]; SelectDBObject(NodeData.Captions[0], NodeData.NodeType);
end; end;
case ObjectType of case SelectedTable.NodeType of
NODETYPE_DB: begin lntDb: begin
if CreateDatabaseForm = nil then if CreateDatabaseForm = nil then
CreateDatabaseForm := TCreateDatabaseForm.Create(Self); CreateDatabaseForm := TCreateDatabaseForm.Create(Self);
CreateDatabaseForm.modifyDB := ObjectName; CreateDatabaseForm.modifyDB := ActiveDatabase;
CreateDatabaseForm.ShowModal; CreateDatabaseForm.ShowModal;
end; end;
NODETYPE_TABLE, NODETYPE_CRASHED_TABLE: begin
if TableEditorForm = nil then lntTable, lntCrashedTable: begin
TableEditorForm := TfrmTableEditor.Create(Self); PlaceObjectEditor(SelectedTable.NodeType);
TableEditorForm.AlterTableName := ObjectName; TableEditor.Init(SelectedTable.Text);
TableEditorForm.ShowModal;
end; end;
NODETYPE_VIEW: begin
if ViewForm = nil then lntView: begin
ViewForm := TfrmView.Create(Self); PlaceObjectEditor(SelectedTable.NodeType);
ViewForm.EditViewName := ObjectName; ViewEditor.Init(SelectedTable.Text);
ViewForm.ShowModal;
end; end;
NODETYPE_FUNCTION, NODETYPE_PROCEDURE: begin
if not Assigned(RoutineEditForm) then lntFunction, lntProcedure: begin
RoutineEditForm := TfrmRoutineEditor.Create(Self); PlaceObjectEditor(SelectedTable.NodeType);
RoutineEditForm.AlterRoutineName := ObjectName; if SelectedTable.NodeType = lntFunction then
if ObjectType = NODETYPE_FUNCTION then RoutineType := 'FUNCTION'
RoutineEditForm.AlterRoutineType := 'FUNCTION'
else else
RoutineEditForm.AlterRoutineType := 'PROCEDURE'; RoutineType := 'PROCEDURE';
RoutineEditForm.ShowModal; RoutineEditor.Init(SelectedTable.Text, RoutineType);
end; end;
end; end;
end; end;
@ -8896,13 +8946,11 @@ procedure TMainForm.ListTablesDblClick(Sender: TObject);
var var
NodeData: PVTreeData; NodeData: PVTreeData;
begin begin
// DoubleClick: Display datagrid for tables and views, editor dialog for routines // DoubleClick: Display editor
debug('ListTablesDblClick()');
if Assigned(ListTables.FocusedNode) then begin
NodeData := ListTables.GetNodeData(ListTables.FocusedNode); NodeData := ListTables.GetNodeData(ListTables.FocusedNode);
case NodeData.NodeType of SelectDBObject(ListTables.Text[ListTables.FocusedNode, ListTables.FocusedColumn], NodeData.NodeType);
NODETYPE_TABLE, NODETYPE_CRASHED_TABLE, NODETYPE_VIEW:
actViewDataExecute(actViewData);
NODETYPE_FUNCTION, NODETYPE_PROCEDURE:
actEditObjectExecute(actEditObject);
end; end;
end; end;

View File

@ -120,7 +120,7 @@ begin
ds := Mainform.FetchDbTableList(DBComboBox.Text); ds := Mainform.FetchDbTableList(DBComboBox.Text);
TablesCheckListBox.Items.Clear; TablesCheckListBox.Items.Clear;
while not ds.Eof do begin while not ds.Eof do begin
if GetDBObjectType(ds.Fields) = NODETYPE_TABLE then if GetDBObjectType(ds.Fields) = lntTable then
TablesCheckListBox.Items.Add(ds.FieldByName(DBO_NAME).AsWideString); TablesCheckListBox.Items.Add(ds.FieldByName(DBO_NAME).AsWideString);
ds.Next; ds.Next;
end; end;

View File

@ -1,30 +1,22 @@
object frmRoutineEditor: TfrmRoutineEditor object frmRoutineEditor: TfrmRoutineEditor
Left = 0 Left = 0
Top = 0 Top = 0
Caption = 'Stored routine editor' Width = 475
ClientHeight = 464 Height = 484
ClientWidth = 384 Constraints.MinHeight = 240
Color = clBtnFace Constraints.MinWidth = 320
Constraints.MinHeight = 500
Constraints.MinWidth = 400
Font.Charset = DEFAULT_CHARSET Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText Font.Color = clWindowText
Font.Height = -11 Font.Height = -11
Font.Name = 'Tahoma' Font.Name = 'Tahoma'
Font.Style = [] Font.Style = []
OldCreateOrder = False ParentFont = False
Position = poMainFormCenter TabOrder = 0
OnClose = FormClose
OnCreate = FormCreate
OnDestroy = FormDestroy
OnShow = FormShow
DesignSize = ( DesignSize = (
384 475
464) 484)
PixelsPerInch = 96
TextHeight = 13
object lblName: TLabel object lblName: TLabel
Left = 8 Left = 3
Top = 11 Top = 11
Width = 31 Width = 31
Height = 13 Height = 13
@ -32,7 +24,7 @@ object frmRoutineEditor: TfrmRoutineEditor
FocusControl = editName FocusControl = editName
end end
object lblType: TLabel object lblType: TLabel
Left = 8 Left = 3
Top = 36 Top = 36
Width = 28 Width = 28
Height = 13 Height = 13
@ -40,7 +32,7 @@ object frmRoutineEditor: TfrmRoutineEditor
FocusControl = comboType FocusControl = comboType
end end
object lblReturns: TLabel object lblReturns: TLabel
Left = 8 Left = 3
Top = 61 Top = 61
Width = 42 Width = 42
Height = 13 Height = 13
@ -48,14 +40,14 @@ object frmRoutineEditor: TfrmRoutineEditor
FocusControl = comboReturns FocusControl = comboReturns
end end
object lblParameters: TLabel object lblParameters: TLabel
Left = 8 Left = 3
Top = 187 Top = 187
Width = 59 Width = 59
Height = 13 Height = 13
Caption = 'Parameters:' Caption = 'Parameters:'
end end
object lblSQL: TLabel object lblSQL: TLabel
Left = 8 Left = 3
Top = 87 Top = 87
Width = 62 Width = 62
Height = 13 Height = 13
@ -63,7 +55,7 @@ object frmRoutineEditor: TfrmRoutineEditor
FocusControl = comboDataAccess FocusControl = comboDataAccess
end end
object lblSecurity: TLabel object lblSecurity: TLabel
Left = 8 Left = 3
Top = 112 Top = 112
Width = 65 Width = 65
Height = 13 Height = 13
@ -71,7 +63,7 @@ object frmRoutineEditor: TfrmRoutineEditor
FocusControl = comboSecurity FocusControl = comboSecurity
end end
object lblComment: TLabel object lblComment: TLabel
Left = 8 Left = 3
Top = 137 Top = 137
Width = 49 Width = 49
Height = 13 Height = 13
@ -79,49 +71,39 @@ object frmRoutineEditor: TfrmRoutineEditor
FocusControl = editComment FocusControl = editComment
end end
object lblSQLcode: TLabel object lblSQLcode: TLabel
Left = 8 Left = 3
Top = 317 Top = 317
Width = 68 Width = 68
Height = 13 Height = 13
Caption = '&Routine body:' Caption = '&Routine body:'
FocusControl = SynMemoBody FocusControl = SynMemoBody
end end
object btnApply: TButton object btnSave: TButton
Left = 301 Left = 165
Top = 432 Top = 455
Width = 75 Width = 75
Height = 25 Height = 25
Anchors = [akRight, akBottom] Anchors = [akLeft, akBottom]
Caption = 'Apply' Caption = 'Save'
TabOrder = 13
OnClick = PostChanges
end
object btnCancel: TButton
Left = 220
Top = 432
Width = 75
Height = 25
Anchors = [akRight, akBottom]
Cancel = True
Caption = 'Cancel'
ModalResult = 2
TabOrder = 12
end
object btnOK: TButton
Left = 139
Top = 432
Width = 75
Height = 25
Anchors = [akRight, akBottom]
Caption = 'OK'
Default = True Default = True
ModalResult = 1 TabOrder = 12
TabOrder = 11
OnClick = PostChanges OnClick = PostChanges
end end
object btnDiscard: TButton
Left = 84
Top = 455
Width = 75
Height = 25
Anchors = [akLeft, akBottom]
Cancel = True
Caption = 'Discard'
ModalResult = 2
TabOrder = 11
OnClick = btnDiscardClick
end
object btnHelp: TButton object btnHelp: TButton
Left = 8 Left = 3
Top = 432 Top = 455
Width = 75 Width = 75
Height = 25 Height = 25
Anchors = [akLeft, akBottom] Anchors = [akLeft, akBottom]
@ -130,9 +112,9 @@ object frmRoutineEditor: TfrmRoutineEditor
OnClick = btnHelpClick OnClick = btnHelpClick
end end
object comboReturns: TComboBox object comboReturns: TComboBox
Left = 100 Left = 95
Top = 58 Top = 58
Width = 276 Width = 377
Height = 21 Height = 21
Anchors = [akLeft, akTop, akRight] Anchors = [akLeft, akTop, akRight]
ItemHeight = 13 ItemHeight = 13
@ -141,9 +123,9 @@ object frmRoutineEditor: TfrmRoutineEditor
OnChange = Modification OnChange = Modification
end end
object comboType: TTntComboBox object comboType: TTntComboBox
Left = 100 Left = 95
Top = 33 Top = 33
Width = 276 Width = 377
Height = 21 Height = 21
Style = csDropDownList Style = csDropDownList
Anchors = [akLeft, akTop, akRight] Anchors = [akLeft, akTop, akRight]
@ -152,9 +134,9 @@ object frmRoutineEditor: TfrmRoutineEditor
OnSelect = comboTypeSelect OnSelect = comboTypeSelect
end end
object editName: TTntEdit object editName: TTntEdit
Left = 100 Left = 95
Top = 8 Top = 8
Width = 276 Width = 377
Height = 21 Height = 21
Anchors = [akLeft, akTop, akRight] Anchors = [akLeft, akTop, akRight]
TabOrder = 0 TabOrder = 0
@ -162,7 +144,7 @@ object frmRoutineEditor: TfrmRoutineEditor
OnChange = editNameChange OnChange = editNameChange
end end
object tlbParameters: TToolBar object tlbParameters: TToolBar
Left = 8 Left = 3
Top = 206 Top = 206
Width = 72 Width = 72
Height = 84 Height = 84
@ -198,9 +180,9 @@ object frmRoutineEditor: TfrmRoutineEditor
end end
end end
object listParameters: TVirtualStringTree object listParameters: TVirtualStringTree
Left = 100 Left = 95
Top = 206 Top = 206
Width = 276 Width = 377
Height = 100 Height = 100
Anchors = [akLeft, akTop, akRight] Anchors = [akLeft, akTop, akRight]
DragImageKind = diMainColumnOnly DragImageKind = diMainColumnOnly
@ -236,7 +218,7 @@ object frmRoutineEditor: TfrmRoutineEditor
item item
Options = [coDraggable, coEnabled, coParentBidiMode, coParentColor, coResizable, coShowDropMark, coVisible, coAllowFocus] Options = [coDraggable, coEnabled, coParentBidiMode, coParentColor, coResizable, coShowDropMark, coVisible, coAllowFocus]
Position = 1 Position = 1
Width = 87 Width = 188
WideText = 'Name' WideText = 'Name'
end end
item item
@ -253,9 +235,9 @@ object frmRoutineEditor: TfrmRoutineEditor
end> end>
end end
object comboDataAccess: TComboBox object comboDataAccess: TComboBox
Left = 100 Left = 95
Top = 84 Top = 84
Width = 276 Width = 377
Height = 21 Height = 21
Style = csDropDownList Style = csDropDownList
Anchors = [akLeft, akTop, akRight] Anchors = [akLeft, akTop, akRight]
@ -264,9 +246,9 @@ object frmRoutineEditor: TfrmRoutineEditor
OnChange = Modification OnChange = Modification
end end
object comboSecurity: TComboBox object comboSecurity: TComboBox
Left = 100 Left = 95
Top = 109 Top = 109
Width = 276 Width = 377
Height = 21 Height = 21
Style = csDropDownList Style = csDropDownList
Anchors = [akLeft, akTop, akRight] Anchors = [akLeft, akTop, akRight]
@ -275,9 +257,9 @@ object frmRoutineEditor: TfrmRoutineEditor
OnChange = Modification OnChange = Modification
end end
object editComment: TTntEdit object editComment: TTntEdit
Left = 100 Left = 95
Top = 134 Top = 134
Width = 276 Width = 377
Height = 21 Height = 21
Anchors = [akLeft, akTop, akRight] Anchors = [akLeft, akTop, akRight]
TabOrder = 5 TabOrder = 5
@ -285,9 +267,9 @@ object frmRoutineEditor: TfrmRoutineEditor
OnChange = Modification OnChange = Modification
end end
object chkDeterministic: TCheckBox object chkDeterministic: TCheckBox
Left = 100 Left = 95
Top = 161 Top = 161
Width = 276 Width = 377
Height = 17 Height = 17
Anchors = [akLeft, akTop, akRight] Anchors = [akLeft, akTop, akRight]
Caption = '&Deterministic' Caption = '&Deterministic'
@ -295,10 +277,10 @@ object frmRoutineEditor: TfrmRoutineEditor
OnClick = Modification OnClick = Modification
end end
object SynMemoBody: TSynMemo object SynMemoBody: TSynMemo
Left = 8 Left = 3
Top = 336 Top = 336
Width = 368 Width = 469
Height = 90 Height = 113
SingleLineMode = False SingleLineMode = False
Anchors = [akLeft, akTop, akRight, akBottom] Anchors = [akLeft, akTop, akRight, akBottom]
Font.Charset = DEFAULT_CHARSET Font.Charset = DEFAULT_CHARSET

View File

@ -8,10 +8,9 @@ uses
VirtualTrees, WideStrings, db, SynRegExpr, WideStrUtils; VirtualTrees, WideStrings, db, SynRegExpr, WideStrUtils;
type type
TfrmRoutineEditor = class(TForm) TfrmRoutineEditor = class(TFrame)
btnApply: TButton; btnSave: TButton;
btnCancel: TButton; btnDiscard: TButton;
btnOK: TButton;
btnHelp: TButton; btnHelp: TButton;
lblName: TLabel; lblName: TLabel;
lblType: TLabel; lblType: TLabel;
@ -34,10 +33,6 @@ type
chkDeterministic: TCheckBox; chkDeterministic: TCheckBox;
lblSQLcode: TLabel; lblSQLcode: TLabel;
SynMemoBody: TSynMemo; SynMemoBody: TSynMemo;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure comboTypeSelect(Sender: TObject); procedure comboTypeSelect(Sender: TObject);
procedure PostChanges(Sender: TObject); procedure PostChanges(Sender: TObject);
procedure btnHelpClick(Sender: TObject); procedure btnHelpClick(Sender: TObject);
@ -68,16 +63,19 @@ type
procedure listParametersPaintText(Sender: TBaseVirtualTree; procedure listParametersPaintText(Sender: TBaseVirtualTree;
const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
TextType: TVSTTextType); TextType: TVSTTextType);
procedure btnDiscardClick(Sender: TObject);
private private
{ Private declarations } { Private declarations }
Parameters: TWideStringList; Parameters: TWideStringList;
FModified: Boolean; FModified: Boolean;
FAlterRoutineName: WideString;
FAlterRoutineType: String;
procedure SetModified(Value: Boolean); procedure SetModified(Value: Boolean);
property Modified: Boolean read FModified write SetModified; property Modified: Boolean read FModified write SetModified;
public public
{ Public declarations } { Public declarations }
AlterRoutineName: WideString; constructor Create(AOwner: TComponent); override;
AlterRoutineType: String; procedure Init(AlterRoutineName: WideString=''; AlterRoutineType: String='');
end; end;
@ -91,13 +89,12 @@ const
DELIM = '|'; DELIM = '|';
procedure TfrmRoutineEditor.FormCreate(Sender: TObject); constructor TfrmRoutineEditor.Create(AOwner: TComponent);
var var
i: Integer; i: Integer;
begin begin
// Restore form dimensions inherited Create(AOwner);
Width := GetRegValue(REGNAME_PROCEDITOR_WIDTH, Width); Align := alClient;
Height := GetRegValue(REGNAME_PROCEDITOR_HEIGHT, Height);
// Combo items in a .dfm are sporadically lost after an IDE restart, // Combo items in a .dfm are sporadically lost after an IDE restart,
// so we set them here to avoid developer annoyance // so we set them here to avoid developer annoyance
comboType.Items.Add('Procedure (doesn''t return a result)'); comboType.Items.Add('Procedure (doesn''t return a result)');
@ -120,16 +117,7 @@ begin
end; end;
procedure TfrmRoutineEditor.FormDestroy(Sender: TObject); procedure TfrmRoutineEditor.Init(AlterRoutineName: WideString=''; AlterRoutineType: String='');
begin
// Store form dimensions
OpenRegistry;
MainReg.WriteInteger(REGNAME_PROCEDITOR_WIDTH, Width);
MainReg.WriteInteger(REGNAME_PROCEDITOR_HEIGHT, Height);
end;
procedure TfrmRoutineEditor.FormShow(Sender: TObject);
var var
ds: TDataSet; ds: TDataSet;
Create: WideString; Create: WideString;
@ -138,34 +126,36 @@ var
rx: TRegExpr; rx: TRegExpr;
i: Integer; i: Integer;
begin begin
editName.Text := AlterRoutineName; FAlterRoutineName := AlterRoutineName;
FAlterRoutineType := AlterRoutineType;
editName.Text := FAlterRoutineName;
comboType.ItemIndex := 0; comboType.ItemIndex := 0;
comboReturns.Text := ''; comboReturns.Text := '';
listParameters.Clear; listParameters.Clear;
Parameters.Clear;
comboDataAccess.ItemIndex := 0; comboDataAccess.ItemIndex := 0;
comboSecurity.ItemIndex := 0; comboSecurity.ItemIndex := 0;
editComment.Clear; editComment.Clear;
SynMemoBody.Text := 'BEGIN'+CRLF+CRLF+'END'; SynMemoBody.Text := 'BEGIN'+CRLF+CRLF+'END';
if editName.Text <> '' then begin if FAlterRoutineName <> '' then begin
// Editing existing routine // Editing existing routine
Mainform.SetEditorTabCaption(Self, FAlterRoutineName);
ds := Mainform.GetResults('SELECT * FROM '+DBNAME_INFORMATION_SCHEMA+'.ROUTINES'+ ds := Mainform.GetResults('SELECT * FROM '+DBNAME_INFORMATION_SCHEMA+'.ROUTINES'+
' WHERE ROUTINE_SCHEMA='+esc(Mainform.ActiveDatabase)+ ' WHERE ROUTINE_SCHEMA='+esc(Mainform.ActiveDatabase)+
' AND ROUTINE_NAME='+esc(AlterRoutineName)+ ' AND ROUTINE_NAME='+esc(FAlterRoutineName)+
' AND ROUTINE_TYPE='+esc(AlterRoutineType) ' AND ROUTINE_TYPE='+esc(FAlterRoutineType)
); );
if ds.RecordCount <> 1 then begin if ds.RecordCount <> 1 then
MessageDlg('Cannot find properties of stored routine '+AlterRoutineName, mtError, [mbOK], 0); Exception.Create('Cannot find properties of stored routine '+FAlterRoutineName);
Close;
end;
ds.First; ds.First;
comboType.ItemIndex := ListIndexByRegExpr(comboType.Items, '^'+AlterRoutineType+'\b'); comboType.ItemIndex := ListIndexByRegExpr(comboType.Items, '^'+FAlterRoutineType+'\b');
chkDeterministic.Checked := ds.FieldByName('IS_DETERMINISTIC').AsString = 'YES'; chkDeterministic.Checked := ds.FieldByName('IS_DETERMINISTIC').AsString = 'YES';
comboReturns.Text := ds.FieldByName('DTD_IDENTIFIER').AsWideString; comboReturns.Text := ds.FieldByName('DTD_IDENTIFIER').AsWideString;
comboDataAccess.ItemIndex := comboDataAccess.Items.IndexOf(ds.FieldByName('SQL_DATA_ACCESS').AsString); comboDataAccess.ItemIndex := comboDataAccess.Items.IndexOf(ds.FieldByName('SQL_DATA_ACCESS').AsString);
comboSecurity.ItemIndex := comboSecurity.Items.IndexOf(ds.FieldByName('SECURITY_TYPE').AsString); comboSecurity.ItemIndex := comboSecurity.Items.IndexOf(ds.FieldByName('SECURITY_TYPE').AsString);
editComment.Text := ds.FieldByName('ROUTINE_COMMENT').AsWideString; editComment.Text := ds.FieldByName('ROUTINE_COMMENT').AsWideString;
SynMemoBody.Text := ds.FieldByName('ROUTINE_DEFINITION').AsWideString; SynMemoBody.Text := ds.FieldByName('ROUTINE_DEFINITION').AsWideString;
Create := Mainform.GetVar('SHOW CREATE '+AlterRoutineType+' '+Mainform.mask(editName.Text), 2); Create := Mainform.GetVar('SHOW CREATE '+FAlterRoutineType+' '+Mainform.mask(editName.Text), 2);
rx := TRegExpr.Create; rx := TRegExpr.Create;
rx.ModifierI := True; rx.ModifierI := True;
rx.ModifierG := False; rx.ModifierG := False;
@ -185,23 +175,15 @@ begin
FreeAndNil(Params); FreeAndNil(Params);
end; end;
FreeAndNil(ds); FreeAndNil(ds);
end; end else
editName.SetFocus; Mainform.SetEditorTabCaption(Self, '');
editNameChange(Sender); editNameChange(Self);
comboTypeSelect(comboType); comboTypeSelect(comboType);
btnRemoveParam.Enabled := Assigned(listParameters.FocusedNode); btnRemoveParam.Enabled := Assigned(listParameters.FocusedNode);
Modified := False; Modified := False;
end; end;
procedure TfrmRoutineEditor.FormClose(Sender: TObject; var Action: TCloseAction);
begin
// Reset edited proc name for the next call
AlterRoutineName := '';
Parameters.Clear;
end;
procedure TfrmRoutineEditor.editNameChange(Sender: TObject); procedure TfrmRoutineEditor.editNameChange(Sender: TObject);
begin begin
editName.Font.Color := clWindowText; editName.Font.Color := clWindowText;
@ -418,12 +400,10 @@ begin
if editName.Text = '' then begin if editName.Text = '' then begin
MessageDlg('Please specify the routine''s name.', mtError, [mbOK], 0); MessageDlg('Please specify the routine''s name.', mtError, [mbOK], 0);
editName.SetFocus; editName.SetFocus;
ModalResult := mrNone;
Exit; Exit;
end else if (ProcOrFunc = 'FUNCTION') and (comboReturns.Text = '') then begin end else if (ProcOrFunc = 'FUNCTION') and (comboReturns.Text = '') then begin
MessageDlg('Please specify the function''s returning datatype.', mtError, [mbOK], 0); MessageDlg('Please specify the function''s returning datatype.', mtError, [mbOK], 0);
comboReturns.SetFocus; comboReturns.SetFocus;
ModalResult := mrNone;
Exit; Exit;
end; end;
@ -448,23 +428,21 @@ begin
BaseSQL := BaseSQL + 'COMMENT ' + esc(editComment.Text)+' '; BaseSQL := BaseSQL + 'COMMENT ' + esc(editComment.Text)+' ';
BaseSQL := BaseSQL + SynMemoBody.Text; BaseSQL := BaseSQL + SynMemoBody.Text;
try
// There is no way to ALTER parameters or the name of it. // There is no way to ALTER parameters or the name of it.
// Create a temp routine, check for syntax errors, then drop the old routine and create it. // Create a temp routine, check for syntax errors, then drop the old routine and create it.
// See also: http://dev.mysql.com/doc/refman/5.0/en/alter-procedure.html // See also: http://dev.mysql.com/doc/refman/5.0/en/alter-procedure.html
if AlterRoutineName <> '' then begin if FAlterRoutineName <> '' then begin
// Create temp name // Create temp name
i := 0; i := 0;
allRoutineNames := Mainform.GetCol('SELECT ROUTINE_NAME FROM '+Mainform.mask(DBNAME_INFORMATION_SCHEMA)+'.'+Mainform.mask('ROUTINES')+ allRoutineNames := Mainform.GetCol('SELECT ROUTINE_NAME FROM '+Mainform.mask(DBNAME_INFORMATION_SCHEMA)+'.'+Mainform.mask('ROUTINES')+
' WHERE ROUTINE_SCHEMA = '+esc(Mainform.ActiveDatabase)+ ' WHERE ROUTINE_SCHEMA = '+esc(Mainform.ActiveDatabase)+
' AND ROUTINE_TYPE = '+esc(ProcOrFunc) ' AND ROUTINE_TYPE = '+esc(ProcOrFunc)
); );
TargetExists := ((editName.Text <> AlterRoutineName) or (ProcOrFunc <> AlterRoutineType)) and TargetExists := ((editName.Text <> FAlterRoutineName) or (ProcOrFunc <> FAlterRoutineType)) and
(allRoutineNames.IndexOf(editName.Text) > -1); (allRoutineNames.IndexOf(editName.Text) > -1);
if TargetExists then begin if TargetExists then begin
if MessageDlg('Routine "'+editName.Text+'" already exists. Overwrite it?', if MessageDlg('Routine "'+editName.Text+'" already exists. Overwrite it?',
mtConfirmation, [mbOk, mbCancel], 0) = mrCancel then begin mtConfirmation, [mbOk, mbCancel], 0) = mrCancel then begin
ModalResult := mrNone;
Exit; Exit;
end; end;
end; end;
@ -479,7 +457,7 @@ begin
// Drop temporary routine, used for syntax checking // Drop temporary routine, used for syntax checking
Mainform.ExecUpdateQuery('DROP '+ProcOrFunc+' IF EXISTS '+Mainform.mask(TempName)); Mainform.ExecUpdateQuery('DROP '+ProcOrFunc+' IF EXISTS '+Mainform.mask(TempName));
// Drop edited routine // Drop edited routine
Mainform.ExecUpdateQuery('DROP '+AlterRoutineType+' IF EXISTS '+Mainform.mask(AlterRoutineName)); Mainform.ExecUpdateQuery('DROP '+FAlterRoutineType+' IF EXISTS '+Mainform.mask(FAlterRoutineName));
if TargetExists then begin if TargetExists then begin
// Drop target routine - overwriting has been confirmed, see above // Drop target routine - overwriting has been confirmed, see above
Mainform.ExecUpdateQuery('DROP '+ProcOrFunc+' IF EXISTS '+Mainform.mask(editName.Text)); Mainform.ExecUpdateQuery('DROP '+ProcOrFunc+' IF EXISTS '+Mainform.mask(editName.Text));
@ -488,23 +466,25 @@ begin
FinalSQL := 'CREATE '+ProcOrFunc+' '+Mainform.mask(editName.Text)+'(' + BaseSQL; FinalSQL := 'CREATE '+ProcOrFunc+' '+Mainform.mask(editName.Text)+'(' + BaseSQL;
Mainform.ExecUpdateQuery(FinalSQL, False, True); Mainform.ExecUpdateQuery(FinalSQL, False, True);
// Set editing name if create/alter query was successful // Set editing name if create/alter query was successful
AlterRoutineName := editName.Text; FAlterRoutineName := editName.Text;
AlterRoutineType := ProcOrFunc; FAlterRoutineType := ProcOrFunc;
Mainform.SetEditorTabCaption(Self, FAlterRoutineName);
Mainform.actRefresh.Execute; Mainform.actRefresh.Execute;
Modified := False; Modified := False;
except
On E:Exception do begin
ModalResult := mrNone;
end;
end;
end; end;
procedure TfrmRoutineEditor.SetModified(Value: Boolean); procedure TfrmRoutineEditor.SetModified(Value: Boolean);
begin begin
FModified := Value; FModified := Value;
btnOK.Enabled := FModified; btnSave.Enabled := FModified;
btnApply.Enabled := FModified; btnDiscard.Enabled := FModified;
end;
procedure TfrmRoutineEditor.btnDiscardClick(Sender: TObject);
begin
Init(FAlterRoutineName, FAlterRoutineType);
end; end;

View File

@ -171,9 +171,9 @@ begin
ds := Mainform.FetchDbTableList(Mainform.Databases[Node.Parent.Index]); ds := Mainform.FetchDbTableList(Mainform.Databases[Node.Parent.Index]);
ds.RecNo := Node.Index+1; ds.RecNo := Node.Index+1;
case GetDBObjectType(ds.Fields) of case GetDBObjectType(ds.Fields) of
NODETYPE_CRASHED_TABLE: ImageIndex := ICONINDEX_CRASHED_TABLE; lntCrashedTable: ImageIndex := ICONINDEX_CRASHED_TABLE;
NODETYPE_TABLE: ImageIndex := ICONINDEX_TABLE; lntTable: ImageIndex := ICONINDEX_TABLE;
NODETYPE_VIEW: ImageIndex := ICONINDEX_VIEW; lntView: ImageIndex := ICONINDEX_VIEW;
end; end;
end; end;
2: ImageIndex := ICONINDEX_FIELD; 2: ImageIndex := ICONINDEX_FIELD;

View File

@ -1,84 +1,62 @@
object frmTableEditor: TfrmTableEditor object frmTableEditor: TfrmTableEditor
Left = 0 Left = 0
Top = 0 Top = 0
Caption = 'Table editor' Width = 607
ClientHeight = 412 Height = 391
ClientWidth = 598
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText Font.Color = clWindowText
Font.Height = -11 Font.Height = -11
Font.Name = 'Tahoma' Font.Name = 'Tahoma'
Font.Style = [] Font.Style = []
OldCreateOrder = False ParentFont = False
Position = poMainFormCenter TabOrder = 0
OnClose = FormClose
OnCreate = FormCreate
OnDestroy = FormDestroy
OnShow = FormShow
DesignSize = ( DesignSize = (
598 607
412) 391)
PixelsPerInch = 96
TextHeight = 13
object SplitterTopBottom: TSplitter object SplitterTopBottom: TSplitter
AlignWithMargins = True AlignWithMargins = True
Left = 8 Left = 3
Top = 158 Top = 153
Width = 582 Width = 601
Height = 8 Height = 8
Cursor = crSizeNS Cursor = crSizeNS
Margins.Left = 8
Margins.Top = 0 Margins.Top = 0
Margins.Right = 8
Margins.Bottom = 0 Margins.Bottom = 0
Align = alTop Align = alTop
ResizeStyle = rsUpdate ResizeStyle = rsUpdate
end end
object lblStatus: TLabel object lblStatus: TLabel
Left = 104 Left = 246
Top = 384 Top = 367
Width = 41 Width = 41
Height = 13 Height = 13
Anchors = [akLeft, akBottom] Anchors = [akLeft, akBottom]
Caption = 'lblStatus' Caption = 'lblStatus'
end end
object btnApply: TButton object btnSave: TButton
Left = 515 Left = 165
Top = 379 Top = 362
Width = 75 Width = 75
Height = 25 Height = 25
Anchors = [akRight, akBottom] Anchors = [akLeft, akBottom]
Caption = 'Apply' Caption = 'Save'
TabOrder = 6
OnClick = btnApplyClick
end
object btnCancel: TButton
Left = 434
Top = 379
Width = 75
Height = 25
Anchors = [akRight, akBottom]
Cancel = True
Caption = 'Cancel'
ModalResult = 2
TabOrder = 5
end
object btnOK: TButton
Left = 353
Top = 379
Width = 75
Height = 25
Anchors = [akRight, akBottom]
Caption = 'OK'
Default = True Default = True
ModalResult = 1 TabOrder = 5
OnClick = btnSaveClick
end
object btnDiscard: TButton
Left = 84
Top = 362
Width = 75
Height = 25
Anchors = [akLeft, akBottom]
Caption = 'Discard'
TabOrder = 4 TabOrder = 4
OnClick = btnApplyClick OnClick = btnDiscardClick
end end
object btnHelp: TButton object btnHelp: TButton
Left = 8 Left = 3
Top = 379 Top = 362
Width = 75 Width = 75
Height = 25 Height = 25
Anchors = [akLeft, akBottom] Anchors = [akLeft, akBottom]
@ -88,17 +66,15 @@ object frmTableEditor: TfrmTableEditor
end end
object listColumns: TVirtualStringTree object listColumns: TVirtualStringTree
AlignWithMargins = True AlignWithMargins = True
Left = 8 Left = 3
Top = 196 Top = 186
Width = 582 Width = 601
Height = 176 Height = 173
Margins.Left = 8 Margins.Bottom = 32
Margins.Top = 8
Margins.Right = 8
Margins.Bottom = 40
Align = alClient Align = alClient
BottomSpace = 60
CheckImageKind = ckSystem CheckImageKind = ckSystem
Constraints.MinHeight = 50 Constraints.MinHeight = 4
DragMode = dmAutomatic DragMode = dmAutomatic
Header.AutoSizeIndex = -1 Header.AutoSizeIndex = -1
Header.DefaultHeight = 17 Header.DefaultHeight = 17
@ -188,18 +164,15 @@ object frmTableEditor: TfrmTableEditor
end end
object PageControlMain: TPageControl object PageControlMain: TPageControl
AlignWithMargins = True AlignWithMargins = True
Left = 8 Left = 3
Top = 8 Top = 3
Width = 582 Width = 601
Height = 150 Height = 150
Margins.Left = 8
Margins.Top = 8
Margins.Right = 8
Margins.Bottom = 0 Margins.Bottom = 0
ActivePage = tabBasic ActivePage = tabSQLCode
Align = alTop Align = alTop
Constraints.MinHeight = 150 Constraints.MinHeight = 150
Constraints.MinWidth = 500 Constraints.MinWidth = 304
Images = MainForm.PngImageListMain Images = MainForm.PngImageListMain
TabOrder = 0 TabOrder = 0
OnChange = PageControlMainChange OnChange = PageControlMainChange
@ -207,7 +180,7 @@ object frmTableEditor: TfrmTableEditor
Caption = 'Basic' Caption = 'Basic'
ImageIndex = 14 ImageIndex = 14
DesignSize = ( DesignSize = (
574 593
121) 121)
object lblName: TLabel object lblName: TLabel
Left = 4 Left = 4
@ -224,9 +197,9 @@ object frmTableEditor: TfrmTableEditor
Caption = 'Comment:' Caption = 'Comment:'
end end
object editName: TTntEdit object editName: TTntEdit
Left = 123 Left = 72
Top = 3 Top = 3
Width = 448 Width = 520
Height = 21 Height = 21
Anchors = [akLeft, akTop, akRight] Anchors = [akLeft, akTop, akRight]
TabOrder = 0 TabOrder = 0
@ -234,10 +207,10 @@ object frmTableEditor: TfrmTableEditor
OnChange = editNameChange OnChange = editNameChange
end end
object memoComment: TTntMemo object memoComment: TTntMemo
Left = 123 Left = 72
Top = 30 Top = 30
Width = 448 Width = 520
Height = 83 Height = 87
Anchors = [akLeft, akTop, akRight, akBottom] Anchors = [akLeft, akTop, akRight, akBottom]
Lines.Strings = ( Lines.Strings = (
'memoComment') 'memoComment')
@ -250,7 +223,7 @@ object frmTableEditor: TfrmTableEditor
Caption = 'Options' Caption = 'Options'
ImageIndex = 39 ImageIndex = 39
DesignSize = ( DesignSize = (
574 593
121) 121)
object lblAutoinc: TLabel object lblAutoinc: TLabel
Left = 4 Left = 4
@ -347,7 +320,7 @@ object frmTableEditor: TfrmTableEditor
object memoUnionTables: TTntMemo object memoUnionTables: TTntMemo
Left = 354 Left = 354
Top = 49 Top = 49
Width = 217 Width = 238
Height = 44 Height = 44
Anchors = [akLeft, akTop, akRight] Anchors = [akLeft, akTop, akRight]
Lines.Strings = ( Lines.Strings = (
@ -358,7 +331,7 @@ object frmTableEditor: TfrmTableEditor
object comboInsertMethod: TComboBox object comboInsertMethod: TComboBox
Left = 354 Left = 354
Top = 95 Top = 95
Width = 217 Width = 238
Height = 21 Height = 21
Style = csDropDownList Style = csDropDownList
Anchors = [akLeft, akTop, akRight] Anchors = [akLeft, akTop, akRight]
@ -377,7 +350,7 @@ object frmTableEditor: TfrmTableEditor
object comboCollation: TComboBox object comboCollation: TComboBox
Left = 354 Left = 354
Top = 3 Top = 3
Width = 104 Width = 119
Height = 21 Height = 21
Style = csDropDownList Style = csDropDownList
Anchors = [akLeft, akTop, akRight] Anchors = [akLeft, akTop, akRight]
@ -389,7 +362,7 @@ object frmTableEditor: TfrmTableEditor
object comboEngine: TComboBox object comboEngine: TComboBox
Left = 354 Left = 354
Top = 26 Top = 26
Width = 217 Width = 238
Height = 21 Height = 21
Style = csDropDownList Style = csDropDownList
Anchors = [akLeft, akTop, akRight] Anchors = [akLeft, akTop, akRight]
@ -399,7 +372,7 @@ object frmTableEditor: TfrmTableEditor
OnSelect = comboEngineSelect OnSelect = comboEngineSelect
end end
object chkCharsetConvert: TCheckBox object chkCharsetConvert: TCheckBox
Left = 464 Left = 481
Top = 5 Top = 5
Width = 107 Width = 107
Height = 17 Height = 17
@ -413,13 +386,13 @@ object frmTableEditor: TfrmTableEditor
Caption = 'Indexes' Caption = 'Indexes'
ImageIndex = 13 ImageIndex = 13
DesignSize = ( DesignSize = (
574 593
121) 121)
object treeIndexes: TVirtualStringTree object treeIndexes: TVirtualStringTree
Left = 75 Left = 75
Top = 3 Top = 3
Width = 251 Width = 300
Height = 110 Height = 114
Anchors = [akLeft, akTop, akRight, akBottom] Anchors = [akLeft, akTop, akRight, akBottom]
DragMode = dmAutomatic DragMode = dmAutomatic
EditDelay = 0 EditDelay = 0
@ -453,7 +426,7 @@ object frmTableEditor: TfrmTableEditor
item item
Options = [coEnabled, coParentBidiMode, coParentColor, coResizable, coShowDropMark, coVisible, coAllowFocus] Options = [coEnabled, coParentBidiMode, coParentColor, coResizable, coShowDropMark, coVisible, coAllowFocus]
Position = 0 Position = 0
Width = 151 Width = 196
WideText = 'Name' WideText = 'Name'
end end
item item
@ -522,10 +495,10 @@ object frmTableEditor: TfrmTableEditor
end end
end end
object StaticText1: TStaticText object StaticText1: TStaticText
Left = 341 Left = 381
Top = 25 Top = 25
Width = 221 Width = 188
Height = 39 Height = 66
Anchors = [akTop, akRight] Anchors = [akTop, akRight]
AutoSize = False AutoSize = False
Caption = Caption =
@ -540,7 +513,7 @@ object frmTableEditor: TfrmTableEditor
object SynMemoSQLcode: TSynMemo object SynMemoSQLcode: TSynMemo
Left = 0 Left = 0
Top = 0 Top = 0
Width = 574 Width = 593
Height = 121 Height = 121
SingleLineMode = False SingleLineMode = False
Align = alClient Align = alClient
@ -568,13 +541,11 @@ object frmTableEditor: TfrmTableEditor
end end
object pnlColumnsTop: TPanel object pnlColumnsTop: TPanel
AlignWithMargins = True AlignWithMargins = True
Left = 8 Left = 3
Top = 166 Top = 161
Width = 582 Width = 601
Height = 22 Height = 22
Margins.Left = 8
Margins.Top = 0 Margins.Top = 0
Margins.Right = 8
Margins.Bottom = 0 Margins.Bottom = 0
Align = alTop Align = alTop
Alignment = taLeftJustify Alignment = taLeftJustify
@ -638,8 +609,8 @@ object frmTableEditor: TfrmTableEditor
end end
object popupIndexes: TPopupMenu object popupIndexes: TPopupMenu
Images = MainForm.PngImageListMain Images = MainForm.PngImageListMain
Left = 296 Left = 344
Top = 376 Top = 360
object menuAddIndex: TMenuItem object menuAddIndex: TMenuItem
Caption = 'Add index' Caption = 'Add index'
ImageIndex = 45 ImageIndex = 45
@ -679,8 +650,8 @@ object frmTableEditor: TfrmTableEditor
end end
object popupColumns: TPopupMenu object popupColumns: TPopupMenu
Images = MainForm.PngImageListMain Images = MainForm.PngImageListMain
Left = 264 Left = 312
Top = 376 Top = 360
object menuAddColumn: TMenuItem object menuAddColumn: TMenuItem
Caption = 'Add column' Caption = 'Add column'
ImageIndex = 45 ImageIndex = 45

View File

@ -8,10 +8,9 @@ uses
SynRegExpr, ActiveX, DB, ExtCtrls, ImgList, SynEdit, SynMemo, Menus; SynRegExpr, ActiveX, DB, ExtCtrls, ImgList, SynEdit, SynMemo, Menus;
type type
TfrmTableEditor = class(TForm) TfrmTableEditor = class(TFrame)
btnApply: TButton; btnSave: TButton;
btnCancel: TButton; btnDiscard: TButton;
btnOK: TButton;
btnHelp: TButton; btnHelp: TButton;
listColumns: TVirtualStringTree; listColumns: TVirtualStringTree;
PageControlMain: TPageControl; PageControlMain: TPageControl;
@ -72,8 +71,6 @@ type
menuMoveUpColumn: TMenuItem; menuMoveUpColumn: TMenuItem;
menuMoveDownColumn: TMenuItem; menuMoveDownColumn: TMenuItem;
chkCharsetConvert: TCheckBox; chkCharsetConvert: TCheckBox;
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure editNameChange(Sender: TObject); procedure editNameChange(Sender: TObject);
procedure Modification(Sender: TObject); procedure Modification(Sender: TObject);
procedure btnAddColumnClick(Sender: TObject); procedure btnAddColumnClick(Sender: TObject);
@ -84,11 +81,9 @@ type
procedure btnHelpClick(Sender: TObject); procedure btnHelpClick(Sender: TObject);
procedure listColumnsGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; procedure listColumnsGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString); Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
procedure FormShow(Sender: TObject);
procedure listColumnsEditing(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; var Allowed: Boolean); procedure listColumnsEditing(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; var Allowed: Boolean);
procedure listColumnsNewText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; NewText: WideString); procedure listColumnsNewText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; NewText: WideString);
procedure btnMoveUpColumnClick(Sender: TObject); procedure btnMoveUpColumnClick(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure btnMoveDownColumnClick(Sender: TObject); procedure btnMoveDownColumnClick(Sender: TObject);
procedure listColumnsDragOver(Sender: TBaseVirtualTree; Source: TObject; Shift: TShiftState; State: TDragState; procedure listColumnsDragOver(Sender: TBaseVirtualTree; Source: TObject; Shift: TShiftState; State: TDragState;
Pt: TPoint; Mode: TDropMode; var Effect: Integer; var Accept: Boolean); Pt: TPoint; Mode: TDropMode; var Effect: Integer; var Accept: Boolean);
@ -105,7 +100,7 @@ type
procedure treeIndexesGetImageIndex(Sender: TBaseVirtualTree; Node: PVirtualNode; Kind: TVTImageKind; Column: TColumnIndex; procedure treeIndexesGetImageIndex(Sender: TBaseVirtualTree; Node: PVirtualNode; Kind: TVTImageKind; Column: TColumnIndex;
var Ghosted: Boolean; var ImageIndex: Integer); var Ghosted: Boolean; var ImageIndex: Integer);
procedure btnClearIndexesClick(Sender: TObject); procedure btnClearIndexesClick(Sender: TObject);
procedure btnApplyClick(Sender: TObject); procedure btnSaveClick(Sender: TObject);
procedure editNumEditChange(Sender: TObject); procedure editNumEditChange(Sender: TObject);
procedure comboEngineSelect(Sender: TObject); procedure comboEngineSelect(Sender: TObject);
procedure listColumnsClick(Sender: TObject); procedure listColumnsClick(Sender: TObject);
@ -130,10 +125,12 @@ type
procedure PageControlMainChange(Sender: TObject); procedure PageControlMainChange(Sender: TObject);
procedure chkCharsetConvertClick(Sender: TObject); procedure chkCharsetConvertClick(Sender: TObject);
procedure treeIndexesClick(Sender: TObject); procedure treeIndexesClick(Sender: TObject);
procedure btnDiscardClick(Sender: TObject);
private private
{ Private declarations } { Private declarations }
FModified: Boolean; FModified: Boolean;
FLoaded: Boolean; FLoaded: Boolean;
FAlterTableName: WideString;
SQLCodeValid: Boolean; SQLCodeValid: Boolean;
Columns, ColumnsChanges, Columns, ColumnsChanges,
Indexes, OldIndexes: TWideStringList; Indexes, OldIndexes: TWideStringList;
@ -154,7 +151,9 @@ type
procedure UpdateSQLcode; procedure UpdateSQLcode;
public public
{ Public declarations } { Public declarations }
AlterTableName: WideString; constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure Init(AlterTableName: WideString='');
end; end;
@ -175,13 +174,13 @@ const
{$R *.dfm} {$R *.dfm}
procedure TfrmTableEditor.FormCreate(Sender: TObject); constructor TfrmTableEditor.Create(AOwner: TComponent);
begin begin
// Restore form dimensions inherited Create(AOwner);
Width := GetRegValue(REGNAME_TABLEEDITOR_WIDTH, Width); // Do not set alClient via DFM! In conjunction with ExplicitXXX properties that
Height := GetRegValue(REGNAME_TABLEEDITOR_HEIGHT, Height); // repeatedly breaks the GUI layout when you reload the project
Align := alClient;
PageControlMain.Height := GetRegValue(REGNAME_TABLEEDITOR_TABSHEIGHT, PageControlMain.Height); PageControlMain.Height := GetRegValue(REGNAME_TABLEEDITOR_TABSHEIGHT, PageControlMain.Height);
SetWindowSizeGrip(Handle, True);
InheritFont(Font); InheritFont(Font);
FixVT(listColumns); FixVT(listColumns);
FixVT(treeIndexes); FixVT(treeIndexes);
@ -202,19 +201,18 @@ begin
end; end;
procedure TfrmTableEditor.FormDestroy(Sender: TObject); destructor TfrmTableEditor.Destroy;
begin begin
// Store form dimensions // Store GUI setup
OpenRegistry; OpenRegistry;
MainReg.WriteInteger(REGNAME_TABLEEDITOR_WIDTH, Width);
MainReg.WriteInteger(REGNAME_TABLEEDITOR_HEIGHT, Height);
MainReg.WriteInteger(REGNAME_TABLEEDITOR_TABSHEIGHT, PageControlMain.Height); MainReg.WriteInteger(REGNAME_TABLEEDITOR_TABSHEIGHT, PageControlMain.Height);
Mainform.SaveListSetup(listColumns); Mainform.SaveListSetup(listColumns);
Mainform.SaveListSetup(treeIndexes); Mainform.SaveListSetup(treeIndexes);
Inherited;
end; end;
procedure TfrmTableEditor.FormShow(Sender: TObject); procedure TfrmTableEditor.Init(AlterTableName: WideString='');
var var
ds: TDataset; ds: TDataset;
Props: TWideStringlist; Props: TWideStringlist;
@ -223,15 +221,20 @@ var
rx: TRegExpr; rx: TRegExpr;
begin begin
SetStatus('Initializing ...'); SetStatus('Initializing ...');
// Always start with "basic" tab activated // Start with "basic" tab activated when just called
if FAlterTableName <> AlterTableName then
PageControlMain.ActivePage := tabBasic; PageControlMain.ActivePage := tabBasic;
Mainform.TableEnginesCombo(comboEngine); Mainform.TableEnginesCombo(comboEngine);
comboCollation.Items.Clear; comboCollation.Items.Clear;
Mainform.GetCollations(comboCollation.Items); Mainform.GetCollations(comboCollation.Items);
FAlterTableName := AlterTableName;
btnClearColumnsClick(Self);
btnClearIndexesClick(Self);
if AlterTableName = '' then begin if FAlterTableName = '' then begin
// Creating new table // Creating new table
editName.Clear; editName.Clear;
Mainform.SetEditorTabCaption(Self, '');
memoComment.Text := ''; memoComment.Text := '';
editAutoInc.Text := ''; editAutoInc.Text := '';
editAvgRowLen.Text := ''; editAvgRowLen.Text := '';
@ -243,12 +246,12 @@ begin
comboInsertMethod.ItemIndex := -1; comboInsertMethod.ItemIndex := -1;
PageControlMain.ActivePage := tabBasic; PageControlMain.ActivePage := tabBasic;
editName.SetFocus;
end else begin end else begin
// Editing existing table // Editing existing table
editName.Text := AlterTableName; editName.Text := FAlterTableName;
ds := Mainform.GetResults('SHOW TABLE STATUS LIKE '+esc(AlterTableName)); Mainform.SetEditorTabCaption(Self, FAlterTableName);
ds := Mainform.GetResults('SHOW TABLE STATUS LIKE '+esc(FAlterTableName));
memoComment.Text := ds.FieldByName(DBO_COMMENT).AsWideString; memoComment.Text := ds.FieldByName(DBO_COMMENT).AsWideString;
if ds.FindField(DBO_ENGINE) <> nil then if ds.FindField(DBO_ENGINE) <> nil then
engine := ds.FieldByName(DBO_ENGINE).AsString engine := ds.FieldByName(DBO_ENGINE).AsString
@ -261,7 +264,7 @@ begin
editAvgRowLen.Text := ds.FieldByName(DBO_AVGROWLEN).AsString; editAvgRowLen.Text := ds.FieldByName(DBO_AVGROWLEN).AsString;
comboRowFormat.ItemIndex := comboRowFormat.Items.IndexOf(ds.FieldByName(DBO_ROWFORMAT).AsString); comboRowFormat.ItemIndex := comboRowFormat.Items.IndexOf(ds.FieldByName(DBO_ROWFORMAT).AsString);
FreeAndNil(ds); FreeAndNil(ds);
CreateTable := Mainform.GetVar('SHOW CREATE TABLE '+Mainform.mask(AlterTableName), 1); CreateTable := Mainform.GetVar('SHOW CREATE TABLE '+Mainform.mask(FAlterTableName), 1);
rx := TRegExpr.Create; rx := TRegExpr.Create;
rx.ModifierI := True; rx.ModifierI := True;
rx.Expression := '\bUNION=\((.+)\)'; rx.Expression := '\bUNION=\((.+)\)';
@ -271,7 +274,8 @@ begin
memoUnionTables.Clear; memoUnionTables.Clear;
FreeAndNil(rx); FreeAndNil(rx);
ds := Mainform.GetResults('SHOW FULL COLUMNS FROM '+Mainform.mask(AlterTableName)); ds := Mainform.GetResults('SHOW FULL COLUMNS FROM '+Mainform.mask(FAlterTableName));
listColumns.BeginUpdate;
while not ds.Eof do begin while not ds.Eof do begin
Props := TWideStringlist.Create; Props := TWideStringlist.Create;
Props.OnChange := ColumnsChange; Props.OnChange := ColumnsChange;
@ -299,8 +303,9 @@ begin
ds.Next; ds.Next;
end; end;
FreeAndNil(ds); FreeAndNil(ds);
listColumns.EndUpdate;
ds := Mainform.GetResults('SHOW KEYS FROM '+Mainform.mask(AlterTableName)); ds := Mainform.GetResults('SHOW KEYS FROM '+Mainform.mask(FAlterTableName));
LastKeyName := ''; LastKeyName := '';
Props := nil; Props := nil;
while not ds.Eof do begin while not ds.Eof do begin
@ -326,7 +331,7 @@ begin
end; end;
// Validate controls // Validate controls
ColumnsChange(Sender); ColumnsChange(Self);
comboEngineSelect(comboEngine); comboEngineSelect(comboEngine);
ValidateColumnControls; ValidateColumnControls;
ValidateIndexControls; ValidateIndexControls;
@ -338,21 +343,29 @@ begin
end; end;
procedure TfrmTableEditor.btnApplyClick(Sender: TObject); procedure TfrmTableEditor.btnDiscardClick(Sender: TObject);
begin
// Reinit GUI, discarding changes
Init(FAlterTableName);
end;
procedure TfrmTableEditor.btnSaveClick(Sender: TObject);
var var
sql: WideString; sql: WideString;
i: Integer; i: Integer;
Props: TWideStringlist; Props: TWideStringlist;
begin begin
// Create or alter table // Create or alter table
if AlterTableName = '' then if FAlterTableName = '' then
sql := ComposeCreateStatement sql := ComposeCreateStatement
else else
sql := ComposeAlterStatement; sql := ComposeAlterStatement;
try Mainform.ExecUpdateQuery(sql);
Mainform.ExecUpdateQuery(sql, False, True);
// Set table name for altering if Apply was clicked // Set table name for altering if Apply was clicked
AlterTableName := editName.Text; FAlterTableName := editName.Text;
Mainform.SetEditorTabCaption(Self, FAlterTableName);
Mainform.tabData.TabVisible := True;
if chkCharsetConvert.Checked then begin if chkCharsetConvert.Checked then begin
// Autoadjust column collations // Autoadjust column collations
for i:=0 to Columns.Count-1 do begin for i:=0 to Columns.Count-1 do begin
@ -365,9 +378,6 @@ begin
end; end;
end; end;
ResetModificationFlags; ResetModificationFlags;
except
ModalResult := mrNone;
end;
end; end;
@ -398,16 +408,6 @@ begin
end; end;
procedure TfrmTableEditor.FormClose(Sender: TObject; var Action: TCloseAction);
begin
// Reset edited table name for the next call
AlterTableName := '';
FLoaded := False;
btnClearColumnsClick(Sender);
btnClearIndexesClick(Sender);
end;
function TfrmTableEditor.ComposeAlterStatement: WideString; function TfrmTableEditor.ComposeAlterStatement: WideString;
var var
Specs, Props, IndexesComposed, OldIndexesComposed: TWideStringlist; Specs, Props, IndexesComposed, OldIndexesComposed: TWideStringlist;
@ -421,7 +421,7 @@ begin
// Compose ALTER query, called by buttons and for SQL code tab // Compose ALTER query, called by buttons and for SQL code tab
SetStatus('Composing ALTER statement ...'); SetStatus('Composing ALTER statement ...');
Specs := TWideStringlist.Create; Specs := TWideStringlist.Create;
if editName.Text <> AlterTableName then if editName.Text <> FAlterTableName then
Specs.Add('RENAME TO ' + Mainform.mask(editName.Text)); Specs.Add('RENAME TO ' + Mainform.mask(editName.Text));
if memoComment.Tag = ModifiedFlag then if memoComment.Tag = ModifiedFlag then
Specs.Add('COMMENT = ' + esc(memoComment.Text)); Specs.Add('COMMENT = ' + esc(memoComment.Text));
@ -532,7 +532,7 @@ begin
Specs.Add('ADD '+IndexesComposed[i]); Specs.Add('ADD '+IndexesComposed[i]);
end; end;
Result := 'ALTER TABLE '+Mainform.mask(AlterTableName) + CRLF + #9 + ImplodeStr(',' + CRLF + #9, Specs); Result := 'ALTER TABLE '+Mainform.mask(FAlterTableName) + CRLF + #9 + ImplodeStr(',' + CRLF + #9, Specs);
FreeAndNil(Specs); FreeAndNil(Specs);
FreeAndNil(IndexesComposed); FreeAndNil(IndexesComposed);
FreeAndNil(OldIndexesComposed); FreeAndNil(OldIndexesComposed);
@ -1010,8 +1010,8 @@ procedure TfrmTableEditor.SetModified(Value: Boolean);
begin begin
// Some value has changed // Some value has changed
FModified := Value; FModified := Value;
btnOK.Enabled := FModified; btnSave.Enabled := FModified;
btnApply.Enabled := FModified; btnDiscard.Enabled := FModified;
SQLCodeValid := False; SQLCodeValid := False;
UpdateSQLcode; UpdateSQLcode;
end; end;
@ -1491,7 +1491,7 @@ begin
if (PageControlMain.ActivePage = tabSQLCode) and (not SQLCodeValid) then begin if (PageControlMain.ActivePage = tabSQLCode) and (not SQLCodeValid) then begin
SynMemoSQLcode.BeginUpdate; SynMemoSQLcode.BeginUpdate;
OldTopLine := SynMemoSQLcode.TopLine; OldTopLine := SynMemoSQLcode.TopLine;
if AlterTableName <> '' then if FAlterTableName <> '' then
SynMemoSQLcode.Text := ComposeAlterStatement SynMemoSQLcode.Text := ComposeAlterStatement
else else
SynMemoSQLcode.Text := ComposeCreateStatement; SynMemoSQLcode.Text := ComposeCreateStatement;
@ -1508,7 +1508,7 @@ begin
listColumns.Header.Columns[8].Color := clBtnFace listColumns.Header.Columns[8].Color := clBtnFace
else else
listColumns.Header.Columns[8].Color := clWindow; listColumns.Header.Columns[8].Color := clWindow;
chkCharsetConvert.Enabled := (AlterTablename <> '') and (comboCollation.ItemIndex > -1); chkCharsetConvert.Enabled := (FAlterTablename <> '') and (comboCollation.ItemIndex > -1);
listColumns.Repaint; listColumns.Repaint;
Modification(Sender); Modification(Sender);
end; end;

View File

@ -6,7 +6,7 @@ interface
uses uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ComCtrls, StdCtrls, CheckLst, ExtCtrls, Buttons, DB, ComCtrls, StdCtrls, CheckLst, ExtCtrls, Buttons, DB,
ToolWin, TntCheckLst, WideStrings, WideStrUtils; ToolWin, TntCheckLst, WideStrings, WideStrUtils, helpers;
{$I const.inc} {$I const.inc}
@ -14,7 +14,7 @@ uses
type type
TPrivilege = class(TObject) TPrivilege = class(TObject)
private private
FDBOType: Byte; FDBOType: TListNodeType;
// Internal Flags // Internal Flags
FDeleted: Boolean; FDeleted: Boolean;
FAdded: Boolean; FAdded: Boolean;
@ -28,7 +28,7 @@ type
SelectedPrivNames: TWideStringList; SelectedPrivNames: TWideStringList;
constructor Create(Fields: TFields; FieldDefs: TDataset = nil; AvoidFieldDefs: TDataSet = nil; CropFieldDefs: TDataSet = nil; SimulateDbField: Boolean = False); constructor Create(Fields: TFields; FieldDefs: TDataset = nil; AvoidFieldDefs: TDataSet = nil; CropFieldDefs: TDataSet = nil; SimulateDbField: Boolean = False);
procedure Merge(Fields: TFields); procedure Merge(Fields: TFields);
property DBOType: Byte read FDBOType; property DBOType: TListNodeType read FDBOType;
property DBOKey: String read GetDBOKey; property DBOKey: String read GetDBOKey;
property DBOPrettyKey: String read GetDBOPrettyKey; property DBOPrettyKey: String read GetDBOPrettyKey;
property PrettyPrivNames: TWideStringList read GetPrettyPrivNames; property PrettyPrivNames: TWideStringList read GetPrettyPrivNames;
@ -202,13 +202,13 @@ type
{ Public declarations } { Public declarations }
end; end;
procedure GetPrivilegeRowKey(Fields: TFields; SimulateDbField: Boolean; out DBOType: Byte; out DBONames: TWideStringList); procedure GetPrivilegeRowKey(Fields: TFields; SimulateDbField: Boolean; out DBOType: TListNodeType; out DBONames: TWideStringList);
implementation implementation
uses uses
main, helpers, selectdbobject; main, selectdbobject;
var var
@ -448,11 +448,11 @@ begin
for i := 0 to u.Privileges.Count - 1 do begin for i := 0 to u.Privileges.Count - 1 do begin
Icon := -1; Icon := -1;
case u.Privileges[i].DBOType of case u.Privileges[i].DBOType of
NODETYPE_DEFAULT: Icon := ICONINDEX_SERVER; lntNone: Icon := ICONINDEX_SERVER;
NODETYPE_DB: Icon := ICONINDEX_DB; lntDb: Icon := ICONINDEX_DB;
NODETYPE_TABLE: Icon := ICONINDEX_TABLE; lntTable: Icon := ICONINDEX_TABLE;
NODETYPE_VIEW: Icon := ICONINDEX_VIEW; lntView: Icon := ICONINDEX_VIEW;
NODETYPE_COLUMN: Icon := ICONINDEX_FIELD; lntColumn: Icon := ICONINDEX_FIELD;
end; end;
pname := u.Privileges[i].DBOPrettyKey; pname := u.Privileges[i].DBOPrettyKey;
if u.Privileges[i].Deleted then begin if u.Privileges[i].Deleted then begin
@ -585,7 +585,7 @@ begin
for i := 0 to priv.PrivNames.Count - 1 do begin for i := 0 to priv.PrivNames.Count - 1 do begin
boxPrivs.Checked[i] := priv.SelectedPrivNames.IndexOf(priv.PrivNames[i]) > -1; boxPrivs.Checked[i] := priv.SelectedPrivNames.IndexOf(priv.PrivNames[i]) > -1;
end; end;
EnableDelete := (priv.DBOType <> NODETYPE_DEFAULT) and EnableDelete := (priv.DBOType <> lntNone) and
(priv.DBOKey <> '%') and (not priv.Deleted); (priv.DBOKey <> '%') and (not priv.Deleted);
end; end;
if comboUsers.ItemIndex > -1 then if comboUsers.ItemIndex > -1 then
@ -1058,28 +1058,28 @@ begin
// Go. // Go.
LogSQL('Applying privilege to account ' + u.Name + '@' + u.Host + ' for ' + p.DBOPrettyKey + '.'); LogSQL('Applying privilege to account ' + u.Name + '@' + u.Host + ' for ' + p.DBOPrettyKey + '.');
case p.DBOType of case p.DBOType of
NODETYPE_DEFAULT: begin lntNone: begin
TableSet := dsUser; TableSet := dsUser;
TableName := mask(PRIVTABLE_USERS); TableName := mask(PRIVTABLE_USERS);
SetFieldName := ''; SetFieldName := '';
end; end;
NODETYPE_DB: begin lntDb: begin
TableSet := dsDb; TableSet := dsDb;
TableName := mask(PRIVTABLE_DB); TableName := mask(PRIVTABLE_DB);
SetFieldName := ''; SetFieldName := '';
end; end;
NODETYPE_TABLE: begin lntTable: begin
TableSet := dsTables; TableSet := dsTables;
TableName := mask(PRIVTABLE_TABLES); TableName := mask(PRIVTABLE_TABLES);
SetFieldName := 'table_priv'; SetFieldName := 'table_priv';
end; end;
NODETYPE_COLUMN: begin lntColumn: begin
TableSet := dsColumns; TableSet := dsColumns;
TableName := mask(PRIVTABLE_COLUMNS); TableName := mask(PRIVTABLE_COLUMNS);
SetFieldName := 'column_priv'; SetFieldName := 'column_priv';
end; end;
else begin else begin
raise Exception.Create('Processed privilege has an undefined db object type: ' + IntToStr(p.DBOType)); raise Exception.Create('Processed privilege has an undefined db object type: ' + IntToStr(Integer(p.DBOType)));
end; end;
end; end;
// Deduce a key for this privilege definition, appropriate for DELETE. // Deduce a key for this privilege definition, appropriate for DELETE.
@ -1092,7 +1092,7 @@ begin
end; end;
end; end;
// Special case: remove redundant privileges in mysql.user. // Special case: remove redundant privileges in mysql.user.
if (p.DBOType = NODETYPE_DB) and (p.DBOKey = '%') then begin if (p.DBOType = lntDb) and (p.DBOKey = '%') then begin
PrivUpdates.Clear; PrivUpdates.Clear;
for k := 0 to p.PrivNames.Count - 1 do begin for k := 0 to p.PrivNames.Count - 1 do begin
if dsUser.FindField(p.PrivNames[k] + '_priv') <> nil then if dsUser.FindField(p.PrivNames[k] + '_priv') <> nil then
@ -1103,7 +1103,7 @@ begin
Exec(sql + AcctWhere); Exec(sql + AcctWhere);
end; end;
// Remove old privilege definition. // Remove old privilege definition.
if (p.DBOType <> NODETYPE_DEFAULT) then begin if (p.DBOType <> lntNone) then begin
sql := 'DELETE FROM ' + db + '.' + TableName; sql := 'DELETE FROM ' + db + '.' + TableName;
Exec(sql + AcctWhere + PrivWhere); Exec(sql + AcctWhere + PrivWhere);
end else begin end else begin
@ -1150,7 +1150,7 @@ begin
PrivUpdates.Add(mask(SetFieldName) + '=' + esc(Delim(PrivValues, False))); PrivUpdates.Add(mask(SetFieldName) + '=' + esc(Delim(PrivValues, False)));
sql := sql + ' SET ' + PrivWhere + ', ' + Delim(PrivUpdates); sql := sql + ' SET ' + PrivWhere + ', ' + Delim(PrivUpdates);
// Special case: UPDATE instead of INSERT for server-level privileges (see further above). // Special case: UPDATE instead of INSERT for server-level privileges (see further above).
if (p.DBOType = NODETYPE_DEFAULT) then begin if (p.DBOType = lntNone) then begin
// Server barfs if we do not set missing defaults, sigh. // Server barfs if we do not set missing defaults, sigh.
PrivValues.Clear; PrivValues.Clear;
if dsUser.FindField('ssl_cipher') <> nil then if dsUser.FindField('ssl_cipher') <> nil then
@ -1166,7 +1166,7 @@ begin
end; end;
Exec(sql); Exec(sql);
// Special case: update redundant column privileges in mysql.tables_priv. // Special case: update redundant column privileges in mysql.tables_priv.
if (p.DBOType = NODETYPE_COLUMN) and (dsTables.FindField('column_priv') <> nil) then begin if (p.DBOType = lntColumn) and (dsTables.FindField('column_priv') <> nil) then begin
// We need to deduce a completely new key because column_priv in mysql.tables_priv does not have a column field next to it, sigh. // We need to deduce a completely new key because column_priv in mysql.tables_priv does not have a column field next to it, sigh.
PrivUpdates.Clear; PrivUpdates.Clear;
PrivUpdates.Add(mask('Host') + '=' + esc(u.Host)); PrivUpdates.Add(mask('Host') + '=' + esc(u.Host));
@ -1471,7 +1471,7 @@ end;
function TPrivileges.FindPrivilege(Fields: TFields; SimulateDbField: Boolean): TPrivilege; function TPrivileges.FindPrivilege(Fields: TFields; SimulateDbField: Boolean): TPrivilege;
var var
i : Integer; i : Integer;
DBOType: Byte; DBOType: TListNodeType;
DBONames: TWideStringList; DBONames: TWideStringList;
begin begin
Result := nil; Result := nil;
@ -1493,7 +1493,7 @@ begin
SetLength(FPrivilegeItems, Length(FPrivilegeItems)+1); SetLength(FPrivilegeItems, Length(FPrivilegeItems)+1);
FPrivilegeItems[Length(FPrivilegeItems)-1] := Result; FPrivilegeItems[Length(FPrivilegeItems)-1] := Result;
// Minimum default privs for a new user should be read only for everything, or? // Minimum default privs for a new user should be read only for everything, or?
if FOwner.Added and (Result.FDBOType = NODETYPE_DB) and (Result.DBOKey = '%') then begin if FOwner.Added and (Result.FDBOType = lntDb) and (Result.DBOKey = '%') then begin
Result.SelectedPrivNames.Add('Select'); Result.SelectedPrivNames.Add('Select');
Result.Modified := True; Result.Modified := True;
end; end;
@ -1629,14 +1629,14 @@ function TPrivilege.GetDBOPrettyKey: String;
begin begin
Result := ''; Result := '';
case FDBOType of case FDBOType of
NODETYPE_DEFAULT: Result := Result + 'Server privileges'; lntNone: Result := Result + 'Server privileges';
NODETYPE_DB: Result := Result + 'Database: '; lntDb: Result := Result + 'Database: ';
NODETYPE_TABLE: Result := Result + 'Table: '; lntTable: Result := Result + 'Table: ';
NODETYPE_COLUMN: Result := Result + 'Column: '; lntColumn: Result := Result + 'Column: ';
end; end;
Result := Result + GetDBOKey; Result := Result + GetDBOKey;
// Special case "db=%" // Special case "db=%"
if (FDBOType = NODETYPE_DB) and (DBOKey = '%') then if (FDBOType = lntDb) and (DBOKey = '%') then
Result := 'All databases'; Result := 'All databases';
end; end;
@ -1663,25 +1663,25 @@ begin
end; end;
procedure GetPrivilegeRowKey(Fields: TFields; SimulateDbField: Boolean; out DBOType: Byte; out DBONames: TWideStringList); procedure GetPrivilegeRowKey(Fields: TFields; SimulateDbField: Boolean; out DBOType: TListNodeType; out DBONames: TWideStringList);
begin begin
DBOType := NODETYPE_DEFAULT; DBOType := lntNone;
DBONames := TWideStringList.Create; DBONames := TWideStringList.Create;
DBONames.Delimiter := '.'; DBONames.Delimiter := '.';
if SimulateDbField then begin if SimulateDbField then begin
DBOType := NODETYPE_DB; DBOType := lntDb;
DBONames.Add('%'); DBONames.Add('%');
end; end;
if Fields.FindField('Db') <> nil then begin if Fields.FindField('Db') <> nil then begin
DBOType := NODETYPE_DB; DBOType := lntDb;
DBONames.Add(Fields.FieldByName('Db').AsString); DBONames.Add(Fields.FieldByName('Db').AsString);
end; end;
if Fields.FindField('Table_name') <> nil then begin if Fields.FindField('Table_name') <> nil then begin
DBOType := NODETYPE_TABLE; DBOType := lntTable;
DBONames.Add(Fields.FieldByName('Table_name').AsString); DBONames.Add(Fields.FieldByName('Table_name').AsString);
end; end;
if Fields.FindField('Column_name') <> nil then begin if Fields.FindField('Column_name') <> nil then begin
DBOType := NODETYPE_COLUMN; DBOType := lntColumn;
DBONames.Add(Fields.FieldByName('Column_name').AsString); DBONames.Add(Fields.FieldByName('Column_name').AsString);
end; end;
end; end;

View File

@ -1,46 +1,38 @@
object frmView: TfrmView object frmView: TfrmView
Left = 0 Left = 0
Top = 0 Top = 0
BorderIcons = [biSystemMenu, biMaximize] Width = 451
Caption = 'frmView' Height = 304
ClientHeight = 275 Constraints.MinHeight = 240
ClientWidth = 422 Constraints.MinWidth = 320
Color = clBtnFace
Constraints.MinHeight = 250
Constraints.MinWidth = 360
Font.Charset = DEFAULT_CHARSET Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText Font.Color = clWindowText
Font.Height = -11 Font.Height = -11
Font.Name = 'Tahoma' Font.Name = 'Tahoma'
Font.Style = [] Font.Style = []
OldCreateOrder = False ParentFont = False
Position = poOwnerFormCenter TabOrder = 0
OnCreate = FormCreate
OnDestroy = FormDestroy
OnShow = FormShow
DesignSize = ( DesignSize = (
422 451
275) 304)
PixelsPerInch = 96
TextHeight = 13
object lblName: TLabel object lblName: TLabel
Left = 8 Left = 3
Top = 8 Top = 6
Width = 31 Width = 31
Height = 13 Height = 13
Caption = 'Name:' Caption = 'Name:'
end end
object lblSelect: TLabel object lblSelect: TLabel
Left = 8 Left = 3
Top = 124 Top = 124
Width = 85 Width = 85
Height = 13 Height = 13
Caption = 'Select statement:' Caption = 'Select statement:'
end end
object editName: TEdit object editName: TEdit
Left = 45 Left = 42
Top = 5 Top = 3
Width = 371 Width = 405
Height = 21 Height = 21
Anchors = [akLeft, akTop, akRight] Anchors = [akLeft, akTop, akRight]
TabOrder = 0 TabOrder = 0
@ -48,9 +40,9 @@ object frmView: TfrmView
OnChange = editNameChange OnChange = editNameChange
end end
object rgAlgorithm: TRadioGroup object rgAlgorithm: TRadioGroup
Left = 8 Left = 3
Top = 32 Top = 32
Width = 201 Width = 206
Height = 86 Height = 86
Caption = 'Algorithm' Caption = 'Algorithm'
ItemIndex = 0 ItemIndex = 0
@ -61,10 +53,10 @@ object frmView: TfrmView
TabOrder = 1 TabOrder = 1
end end
object SynMemoSelect: TSynMemo object SynMemoSelect: TSynMemo
Left = 8 Left = 3
Top = 143 Top = 143
Width = 408 Width = 444
Height = 95 Height = 128
SingleLineMode = False SingleLineMode = False
Anchors = [akLeft, akTop, akRight, akBottom] Anchors = [akLeft, akTop, akRight, akBottom]
Font.Charset = DEFAULT_CHARSET Font.Charset = DEFAULT_CHARSET
@ -97,33 +89,32 @@ object frmView: TfrmView
ShortCut = 16473 ShortCut = 16473
end> end>
end end
object btnCancel: TButton object btnDiscard: TButton
Left = 341 Left = 84
Top = 244 Top = 276
Width = 75 Width = 75
Height = 25 Height = 25
Anchors = [akRight, akBottom] Anchors = [akLeft, akBottom]
Cancel = True Cancel = True
Caption = 'Cancel' Caption = 'Discard'
ModalResult = 2
TabOrder = 3 TabOrder = 3
OnClick = btnDiscardClick
end end
object btnOK: TButton object btnSave: TButton
Left = 260 Left = 162
Top = 244 Top = 276
Width = 75 Width = 75
Height = 25 Height = 25
Anchors = [akRight, akBottom] Anchors = [akLeft, akBottom]
Caption = 'OK' Caption = 'Save'
Default = True Default = True
ModalResult = 1
TabOrder = 4 TabOrder = 4
OnClick = btnOKClick OnClick = btnSaveClick
end end
object rgCheck: TRadioGroup object rgCheck: TRadioGroup
Left = 215 Left = 215
Top = 32 Top = 32
Width = 201 Width = 232
Height = 86 Height = 86
Anchors = [akLeft, akTop, akRight] Anchors = [akLeft, akTop, akRight]
Caption = 'Check option for updates' Caption = 'Check option for updates'
@ -135,8 +126,8 @@ object frmView: TfrmView
TabOrder = 5 TabOrder = 5
end end
object btnHelp: TButton object btnHelp: TButton
Left = 8 Left = 3
Top = 244 Top = 276
Width = 75 Width = 75
Height = 25 Height = 25
Anchors = [akLeft, akBottom] Anchors = [akLeft, akBottom]

View File

@ -7,27 +7,27 @@ uses
Dialogs, StdCtrls, ComCtrls, SynEdit, SynMemo, ExtCtrls, DB, SynRegExpr; Dialogs, StdCtrls, ComCtrls, SynEdit, SynMemo, ExtCtrls, DB, SynRegExpr;
type type
TfrmView = class(TForm) TfrmView = class(TFrame)
editName: TEdit; editName: TEdit;
lblName: TLabel; lblName: TLabel;
rgAlgorithm: TRadioGroup; rgAlgorithm: TRadioGroup;
SynMemoSelect: TSynMemo; SynMemoSelect: TSynMemo;
lblSelect: TLabel; lblSelect: TLabel;
btnCancel: TButton; btnDiscard: TButton;
btnOK: TButton; btnSave: TButton;
rgCheck: TRadioGroup; rgCheck: TRadioGroup;
btnHelp: TButton; btnHelp: TButton;
procedure btnHelpClick(Sender: TObject); procedure btnHelpClick(Sender: TObject);
procedure btnOKClick(Sender: TObject); procedure btnSaveClick(Sender: TObject);
procedure editNameChange(Sender: TObject); procedure editNameChange(Sender: TObject);
procedure FormDestroy(Sender: TObject); procedure btnDiscardClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormShow(Sender: TObject);
private private
{ Private declarations } { Private declarations }
FEditViewName: WideString;
public public
{ Public declarations } { Public declarations }
EditViewName: String; constructor Create(AOwner: TComponent); override;
procedure Init(EditViewName: WideString='');
end; end;
@ -39,49 +39,37 @@ uses main, helpers;
{** {**
FormCreate: Restore GUI setup Create: Restore GUI setup
} }
procedure TfrmView.FormCreate(Sender: TObject); constructor TfrmView.Create(AOwner: TComponent);
begin begin
Width := GetRegValue(REGNAME_VIEWWINWIDTH, Width); inherited Create(AOwner);
Height := GetRegValue(REGNAME_VIEWWINHEIGHT, Height); Align := alClient;
SynMemoSelect.Highlighter := Mainform.SynSQLSyn1; SynMemoSelect.Highlighter := Mainform.SynSQLSyn1;
SynMemoSelect.Font := Mainform.SynMemoQuery.Font; SynMemoSelect.Font := Mainform.SynMemoQuery.Font;
SetWindowSizeGrip( Self.Handle, True );
InheritFont(Font); InheritFont(Font);
end; end;
{**
FormDestroy: Save GUI setup
}
procedure TfrmView.FormDestroy(Sender: TObject);
begin
OpenRegistry;
MainReg.WriteInteger( REGNAME_VIEWWINWIDTH, Width );
MainReg.WriteInteger( REGNAME_VIEWWINHEIGHT, Height );
Close;
end;
{** {**
FormShow: Fill controls with content in edit mode FormShow: Fill controls with content in edit mode
} }
procedure TfrmView.FormShow(Sender: TObject); procedure TfrmView.Init(EditViewName: WideString='');
var var
ds: TDataset; ds: TDataset;
db: String; db: String;
rx: TRegExpr; rx: TRegExpr;
begin begin
if EditViewName <> '' then begin FEditViewName := EditViewName;
if FEditViewName <> '' then begin
// Edit mode // Edit mode
Caption := 'Edit view ...'; editName.Text := FEditViewName;
editName.Text := EditViewName; Mainform.SetEditorTabCaption(Self, FEditViewName);
db := Mainform.ActiveDatabase; db := Mainform.ActiveDatabase;
ds := Mainform.GetResults('SELECT * FROM '+Mainform.mask(DBNAME_INFORMATION_SCHEMA)+'.VIEWS ' + ds := Mainform.GetResults('SELECT * FROM '+Mainform.mask(DBNAME_INFORMATION_SCHEMA)+'.VIEWS ' +
'WHERE TABLE_SCHEMA = '+esc(db)+' AND TABLE_NAME = '+esc(EditViewName)); 'WHERE TABLE_SCHEMA = '+esc(db)+' AND TABLE_NAME = '+esc(FEditViewName));
if ds.RecordCount = 0 then if ds.RecordCount = 0 then
raise Exception.Create('Can''t find view definition for "'+EditViewName+'" in '+DBNAME_INFORMATION_SCHEMA); raise Exception.Create('Can''t find view definition for "'+FEditViewName+'" in '+DBNAME_INFORMATION_SCHEMA);
// Algorithm is not changeable as we cannot look up its current state! // Algorithm is not changeable as we cannot look up its current state!
rgAlgorithm.Enabled := False; rgAlgorithm.Enabled := False;
rgAlgorithm.ItemIndex := 0; rgAlgorithm.ItemIndex := 0;
@ -96,7 +84,7 @@ begin
rx.Free; rx.Free;
end else begin end else begin
// Create mode // Create mode
Caption := 'Create view ...'; Mainform.SetEditorTabCaption(Self, '');
editName.Text := 'myview'; editName.Text := 'myview';
rgAlgorithm.Enabled := True; rgAlgorithm.Enabled := True;
rgAlgorithm.ItemIndex := 0; rgAlgorithm.ItemIndex := 0;
@ -105,7 +93,7 @@ begin
SynMemoSelect.Text := 'SELECT '; SynMemoSelect.Text := 'SELECT ';
end; end;
// Ensure name is validated // Ensure name is validated
editNameChange(Sender); editNameChange(Self);
end; end;
@ -114,12 +102,12 @@ end;
} }
procedure TfrmView.editNameChange(Sender: TObject); procedure TfrmView.editNameChange(Sender: TObject);
begin begin
btnOK.Enabled := False; btnSave.Enabled := False;
try try
ensureValidIdentifier( editName.Text ); ensureValidIdentifier( editName.Text );
editName.Font.Color := clWindowText; editName.Font.Color := clWindowText;
editName.Color := clWindow; editName.Color := clWindow;
btnOK.Enabled := True; btnSave.Enabled := True;
except except
editName.Font.Color := clRed; editName.Font.Color := clRed;
editName.Color := clYellow; editName.Color := clYellow;
@ -134,7 +122,7 @@ procedure TfrmView.btnHelpClick(Sender: TObject);
var var
keyword: String; keyword: String;
begin begin
if EditViewName = '' then if FEditViewName = '' then
keyword := 'CREATE VIEW' keyword := 'CREATE VIEW'
else else
keyword := 'ALTER VIEW'; keyword := 'ALTER VIEW';
@ -142,20 +130,27 @@ begin
end; end;
procedure TfrmView.btnDiscardClick(Sender: TObject);
begin
// Reinit editor, discarding changes
Init(FEditViewName);
end;
{** {**
Apply changes: Compose and execute SQL Apply changes: Compose and execute SQL
} }
procedure TfrmView.btnOKClick(Sender: TObject); procedure TfrmView.btnSaveClick(Sender: TObject);
var var
sql, viewname, renamed: String; sql, viewname, renamed: String;
begin begin
// Compose CREATE or ALTER statement // Compose CREATE or ALTER statement
if EditViewName = '' then begin if FEditViewName = '' then begin
sql := 'CREATE '; sql := 'CREATE ';
viewname := editName.Text; viewname := editName.Text;
end else begin end else begin
sql := 'ALTER '; sql := 'ALTER ';
viewname := EditViewName; viewname := FEditViewName;
end; end;
viewname := Mainform.mask(viewname); viewname := Mainform.mask(viewname);
if rgAlgorithm.Enabled and (rgAlgorithm.ItemIndex > -1) then if rgAlgorithm.Enabled and (rgAlgorithm.ItemIndex > -1) then
@ -165,20 +160,13 @@ begin
sql := sql + 'WITH '+Uppercase(rgCheck.Items[rgCheck.ItemIndex])+' CHECK OPTION'; sql := sql + 'WITH '+Uppercase(rgCheck.Items[rgCheck.ItemIndex])+' CHECK OPTION';
// Execute query and keep form open in any error case // Execute query and keep form open in any error case
try
Mainform.ExecUpdateQuery(sql); Mainform.ExecUpdateQuery(sql);
// Probably rename view // Probably rename view
if (EditViewName <> '') and (EditViewName <> editName.Text) then begin if (FEditViewName <> '') and (FEditViewName <> editName.Text) then begin
renamed := Mainform.mask(editName.Text); renamed := Mainform.mask(editName.Text);
Mainform.ExecUpdateQuery('RENAME TABLE '+viewname + ' TO '+renamed); Mainform.ExecUpdateQuery('RENAME TABLE '+viewname + ' TO '+renamed);
end; end;
Mainform.RefreshTreeDB(Mainform.ActiveDatabase); Mainform.RefreshTreeDB(Mainform.ActiveDatabase);
except
on E: THandledSQLError do begin
MessageDlg(E.Message, mtError, [mbOK], 0);
ModalResult := mrNone;
end;
end;
end; end;