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_SQLHELPPLWIDTH = 'SQLHelp_PnlLeftWidth';
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_HOST = 'Host';
DEFAULT_HOST = '127.0.0.1';
@ -164,10 +160,6 @@ const
REGNAME_LAST_UPDATECHECK = 'UpdatecheckLastrun';
REGNAME_MAINTWINWIDTH = 'Maintenance_WindowWidth';
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_WINHEIGHT = 'Usermanager_WindowHeight';
REGNAME_SELECTDBO_WINWIDTH = 'SelectDBO_WindowWidth';
@ -262,16 +254,6 @@ const
TXT_ASC = 'ASC'; // Used for caption of "Direction"-button
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.
GRIDMAXDATA: Integer = 256;

View File

@ -349,7 +349,7 @@ begin
checkListTables.Items.Clear;
ds := Mainform.FetchDbTableList(comboSelectDatabase.Text);
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);
ds.Next;
end;

View File

@ -15,11 +15,17 @@ uses Classes, SysUtils, Graphics, db, clipbrd, dialogs,
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
TVTreeData = record
Captions: TWideStringList;
ImageIndex: Integer;
NodeType: Byte;
NodeType: TListNodeType;
end;
PVTreedata = ^TVTreeData;
@ -160,11 +166,11 @@ type
function FormatByteNumber( Bytes: String; Decimals: Byte = 1 ): String; Overload;
function FormatTimeNumber( Seconds: Cardinal ): 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 );
function Pos2(const Needle, HayStack: string; const StartPos: Integer) : Integer;
function GetTempDir: String;
function GetDBObjectType( TableStatus: TFields ): Byte;
function GetDBObjectType( TableStatus: TFields ): TListNodeType;
procedure SetWindowSizeGrip(hWnd: HWND; Enable: boolean);
procedure SaveUnicodeFile(Filename: String; Text: WideString);
function CreateUnicodeFileStream(Filename: String): TFileStream;
@ -2217,7 +2223,7 @@ end;
Return a TStringList with captions from all selected nodes in a VirtualTree
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
SelectedNodes : TNodeArray;
NodeData: PVTreeData;
@ -2232,7 +2238,7 @@ begin
for i := 0 to Length(SelectedNodes) - 1 do
begin
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
Result.Add( NodeData.Captions[Column] );
end;
@ -2241,7 +2247,7 @@ begin
// Fetch all nodes
a := Mainform.GetVTreeDataArray( VT )^;
for i := 0 to High(a) do begin
if (OnlyNodeType = NODETYPE_DEFAULT)
if (OnlyNodeType = lntNone)
or (a[i].NodeType = OnlyNodeType) then
Result.Add( a[i].Captions[ Column ] );
end;
@ -2296,7 +2302,7 @@ end;
// 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
t: String;
begin
@ -2308,28 +2314,28 @@ begin
but for views which is missing its tables, it says
"Views bla references invalid..."
}
Result := NODETYPE_TABLE;
Result := lntTable;
if TableStatus.FindField('Type') <> nil then begin
t := TableStatus.FindField('Type').AsString;
if t = 'BASE TABLE' then
Result := NODETYPE_TABLE
Result := lntTable
else if t = 'VIEW' then
Result := NODETYPE_VIEW
Result := lntView
else if t = 'FUNCTION' then
Result := NODETYPE_FUNCTION
Result := lntFunction
else if t = 'PROCEDURE' then
Result := NODETYPE_PROCEDURE;
Result := lntProcedure;
end else begin
if
TableStatus[1].IsNull and // Engine column is NULL for views
TableStatus[2].IsNull and
(Pos('VIEW', UpperCase(TableStatus.FieldByName(DBO_COMMENT).AsWideString)) > 0)
then Result := NODETYPE_VIEW;
then Result := lntView;
if
TableStatus[1].IsNull and
TableStatus[2].IsNull and
(Pos('MARKED AS CRASHED', UpperCase(TableStatus.FieldByName(DBO_COMMENT).AsWideString)) > 0)
then Result := NODETYPE_CRASHED_TABLE;
then Result := lntCrashedTable;
end;
end;

View File

@ -111,7 +111,7 @@ begin
ComboBoxTables.Items.Clear;
ds := Mainform.FetchDbTableList(ComboBoxDBs.Text);
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);
ds.Next;
end;

View File

@ -146,10 +146,10 @@ begin
// read tables from db
comboTable.Items.Clear;
seldb := Mainform.ActiveDatabase;
seltable := Mainform.SelectedTable;
seltable := Mainform.SelectedTable.Text;
ds := Mainform.FetchDbTableList(comboDatabase.Text);
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);
count := comboTable.Items.Count-1;
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.PaintOptions = [toHideFocusRect, toHotTrack, toShowButtons, toShowDropmark, toShowTreeLines, toThemeAware, toUseBlendedImages, toUseExplorerTheme, toHideTreeLinesIfThemed]
TreeOptions.SelectionOptions = [toRightClickSelect]
OnChange = DBtreeChange
OnDblClick = DBtreeDblClick
OnExpanded = DBtreeExpanded
OnFocusChanged = DBtreeFocusChanged
OnGetText = DBtreeGetText
OnPaintText = DBtreePaintText
OnGetImageIndex = DBtreeGetImageIndex
@ -917,6 +917,10 @@ object MainForm: TMainForm
end>
end
end
object tabEditor: TTabSheet
Caption = 'Table'
ImageIndex = 14
end
object tabData: TTabSheet
Caption = 'Data'
ImageIndex = 41
@ -2122,13 +2126,6 @@ object MainForm: TMainForm
ImageIndex = 119
OnExecute = actCreateRoutineExecute
end
object actViewData: TAction
Category = 'Data'
Caption = 'Data ...'
Hint = 'Displays data grid and allows row editing'
ImageIndex = 41
OnExecute = actViewDataExecute
end
object actEditObject: TAction
Category = 'Database'
Caption = 'Edit'
@ -5850,12 +5847,6 @@ object MainForm: TMainForm
OnPopup = popupDBPopup
Left = 136
Top = 64
object menuViewData: TMenuItem
Action = actViewData
end
object N16: TMenuItem
Caption = '-'
end
object menuEditObject: TMenuItem
Action = actEditObject
ShortCut = 32781

View File

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

View File

@ -120,7 +120,7 @@ begin
ds := Mainform.FetchDbTableList(DBComboBox.Text);
TablesCheckListBox.Items.Clear;
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);
ds.Next;
end;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -6,7 +6,7 @@ interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ComCtrls, StdCtrls, CheckLst, ExtCtrls, Buttons, DB,
ToolWin, TntCheckLst, WideStrings, WideStrUtils;
ToolWin, TntCheckLst, WideStrings, WideStrUtils, helpers;
{$I const.inc}
@ -14,7 +14,7 @@ uses
type
TPrivilege = class(TObject)
private
FDBOType: Byte;
FDBOType: TListNodeType;
// Internal Flags
FDeleted: Boolean;
FAdded: Boolean;
@ -28,7 +28,7 @@ type
SelectedPrivNames: TWideStringList;
constructor Create(Fields: TFields; FieldDefs: TDataset = nil; AvoidFieldDefs: TDataSet = nil; CropFieldDefs: TDataSet = nil; SimulateDbField: Boolean = False);
procedure Merge(Fields: TFields);
property DBOType: Byte read FDBOType;
property DBOType: TListNodeType read FDBOType;
property DBOKey: String read GetDBOKey;
property DBOPrettyKey: String read GetDBOPrettyKey;
property PrettyPrivNames: TWideStringList read GetPrettyPrivNames;
@ -202,13 +202,13 @@ type
{ Public declarations }
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
uses
main, helpers, selectdbobject;
main, selectdbobject;
var
@ -448,11 +448,11 @@ begin
for i := 0 to u.Privileges.Count - 1 do begin
Icon := -1;
case u.Privileges[i].DBOType of
NODETYPE_DEFAULT: Icon := ICONINDEX_SERVER;
NODETYPE_DB: Icon := ICONINDEX_DB;
NODETYPE_TABLE: Icon := ICONINDEX_TABLE;
NODETYPE_VIEW: Icon := ICONINDEX_VIEW;
NODETYPE_COLUMN: Icon := ICONINDEX_FIELD;
lntNone: Icon := ICONINDEX_SERVER;
lntDb: Icon := ICONINDEX_DB;
lntTable: Icon := ICONINDEX_TABLE;
lntView: Icon := ICONINDEX_VIEW;
lntColumn: Icon := ICONINDEX_FIELD;
end;
pname := u.Privileges[i].DBOPrettyKey;
if u.Privileges[i].Deleted then begin
@ -585,7 +585,7 @@ begin
for i := 0 to priv.PrivNames.Count - 1 do begin
boxPrivs.Checked[i] := priv.SelectedPrivNames.IndexOf(priv.PrivNames[i]) > -1;
end;
EnableDelete := (priv.DBOType <> NODETYPE_DEFAULT) and
EnableDelete := (priv.DBOType <> lntNone) and
(priv.DBOKey <> '%') and (not priv.Deleted);
end;
if comboUsers.ItemIndex > -1 then
@ -1058,28 +1058,28 @@ begin
// Go.
LogSQL('Applying privilege to account ' + u.Name + '@' + u.Host + ' for ' + p.DBOPrettyKey + '.');
case p.DBOType of
NODETYPE_DEFAULT: begin
lntNone: begin
TableSet := dsUser;
TableName := mask(PRIVTABLE_USERS);
SetFieldName := '';
end;
NODETYPE_DB: begin
lntDb: begin
TableSet := dsDb;
TableName := mask(PRIVTABLE_DB);
SetFieldName := '';
end;
NODETYPE_TABLE: begin
lntTable: begin
TableSet := dsTables;
TableName := mask(PRIVTABLE_TABLES);
SetFieldName := 'table_priv';
end;
NODETYPE_COLUMN: begin
lntColumn: begin
TableSet := dsColumns;
TableName := mask(PRIVTABLE_COLUMNS);
SetFieldName := 'column_priv';
end;
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;
// Deduce a key for this privilege definition, appropriate for DELETE.
@ -1092,7 +1092,7 @@ begin
end;
end;
// 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;
for k := 0 to p.PrivNames.Count - 1 do begin
if dsUser.FindField(p.PrivNames[k] + '_priv') <> nil then
@ -1103,7 +1103,7 @@ begin
Exec(sql + AcctWhere);
end;
// Remove old privilege definition.
if (p.DBOType <> NODETYPE_DEFAULT) then begin
if (p.DBOType <> lntNone) then begin
sql := 'DELETE FROM ' + db + '.' + TableName;
Exec(sql + AcctWhere + PrivWhere);
end else begin
@ -1150,7 +1150,7 @@ begin
PrivUpdates.Add(mask(SetFieldName) + '=' + esc(Delim(PrivValues, False)));
sql := sql + ' SET ' + PrivWhere + ', ' + Delim(PrivUpdates);
// 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.
PrivValues.Clear;
if dsUser.FindField('ssl_cipher') <> nil then
@ -1166,7 +1166,7 @@ begin
end;
Exec(sql);
// 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.
PrivUpdates.Clear;
PrivUpdates.Add(mask('Host') + '=' + esc(u.Host));
@ -1471,7 +1471,7 @@ end;
function TPrivileges.FindPrivilege(Fields: TFields; SimulateDbField: Boolean): TPrivilege;
var
i : Integer;
DBOType: Byte;
DBOType: TListNodeType;
DBONames: TWideStringList;
begin
Result := nil;
@ -1493,7 +1493,7 @@ begin
SetLength(FPrivilegeItems, Length(FPrivilegeItems)+1);
FPrivilegeItems[Length(FPrivilegeItems)-1] := Result;
// 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.Modified := True;
end;
@ -1629,14 +1629,14 @@ function TPrivilege.GetDBOPrettyKey: String;
begin
Result := '';
case FDBOType of
NODETYPE_DEFAULT: Result := Result + 'Server privileges';
NODETYPE_DB: Result := Result + 'Database: ';
NODETYPE_TABLE: Result := Result + 'Table: ';
NODETYPE_COLUMN: Result := Result + 'Column: ';
lntNone: Result := Result + 'Server privileges';
lntDb: Result := Result + 'Database: ';
lntTable: Result := Result + 'Table: ';
lntColumn: Result := Result + 'Column: ';
end;
Result := Result + GetDBOKey;
// Special case "db=%"
if (FDBOType = NODETYPE_DB) and (DBOKey = '%') then
if (FDBOType = lntDb) and (DBOKey = '%') then
Result := 'All databases';
end;
@ -1663,25 +1663,25 @@ begin
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
DBOType := NODETYPE_DEFAULT;
DBOType := lntNone;
DBONames := TWideStringList.Create;
DBONames.Delimiter := '.';
if SimulateDbField then begin
DBOType := NODETYPE_DB;
DBOType := lntDb;
DBONames.Add('%');
end;
if Fields.FindField('Db') <> nil then begin
DBOType := NODETYPE_DB;
DBOType := lntDb;
DBONames.Add(Fields.FieldByName('Db').AsString);
end;
if Fields.FindField('Table_name') <> nil then begin
DBOType := NODETYPE_TABLE;
DBOType := lntTable;
DBONames.Add(Fields.FieldByName('Table_name').AsString);
end;
if Fields.FindField('Column_name') <> nil then begin
DBOType := NODETYPE_COLUMN;
DBOType := lntColumn;
DBONames.Add(Fields.FieldByName('Column_name').AsString);
end;
end;

View File

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

View File

@ -7,27 +7,27 @@ uses
Dialogs, StdCtrls, ComCtrls, SynEdit, SynMemo, ExtCtrls, DB, SynRegExpr;
type
TfrmView = class(TForm)
TfrmView = class(TFrame)
editName: TEdit;
lblName: TLabel;
rgAlgorithm: TRadioGroup;
SynMemoSelect: TSynMemo;
lblSelect: TLabel;
btnCancel: TButton;
btnOK: TButton;
btnDiscard: TButton;
btnSave: TButton;
rgCheck: TRadioGroup;
btnHelp: TButton;
procedure btnHelpClick(Sender: TObject);
procedure btnOKClick(Sender: TObject);
procedure btnSaveClick(Sender: TObject);
procedure editNameChange(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure btnDiscardClick(Sender: TObject);
private
{ Private declarations }
FEditViewName: WideString;
public
{ Public declarations }
EditViewName: String;
constructor Create(AOwner: TComponent); override;
procedure Init(EditViewName: WideString='');
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
Width := GetRegValue(REGNAME_VIEWWINWIDTH, Width);
Height := GetRegValue(REGNAME_VIEWWINHEIGHT, Height);
inherited Create(AOwner);
Align := alClient;
SynMemoSelect.Highlighter := Mainform.SynSQLSyn1;
SynMemoSelect.Font := Mainform.SynMemoQuery.Font;
SetWindowSizeGrip( Self.Handle, True );
InheritFont(Font);
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
}
procedure TfrmView.FormShow(Sender: TObject);
procedure TfrmView.Init(EditViewName: WideString='');
var
ds: TDataset;
db: String;
rx: TRegExpr;
begin
if EditViewName <> '' then begin
FEditViewName := EditViewName;
if FEditViewName <> '' then begin
// Edit mode
Caption := 'Edit view ...';
editName.Text := EditViewName;
editName.Text := FEditViewName;
Mainform.SetEditorTabCaption(Self, FEditViewName);
db := Mainform.ActiveDatabase;
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
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!
rgAlgorithm.Enabled := False;
rgAlgorithm.ItemIndex := 0;
@ -96,7 +84,7 @@ begin
rx.Free;
end else begin
// Create mode
Caption := 'Create view ...';
Mainform.SetEditorTabCaption(Self, '');
editName.Text := 'myview';
rgAlgorithm.Enabled := True;
rgAlgorithm.ItemIndex := 0;
@ -105,7 +93,7 @@ begin
SynMemoSelect.Text := 'SELECT ';
end;
// Ensure name is validated
editNameChange(Sender);
editNameChange(Self);
end;
@ -114,12 +102,12 @@ end;
}
procedure TfrmView.editNameChange(Sender: TObject);
begin
btnOK.Enabled := False;
btnSave.Enabled := False;
try
ensureValidIdentifier( editName.Text );
editName.Font.Color := clWindowText;
editName.Color := clWindow;
btnOK.Enabled := True;
btnSave.Enabled := True;
except
editName.Font.Color := clRed;
editName.Color := clYellow;
@ -134,7 +122,7 @@ procedure TfrmView.btnHelpClick(Sender: TObject);
var
keyword: String;
begin
if EditViewName = '' then
if FEditViewName = '' then
keyword := 'CREATE VIEW'
else
keyword := 'ALTER VIEW';
@ -142,20 +130,27 @@ begin
end;
procedure TfrmView.btnDiscardClick(Sender: TObject);
begin
// Reinit editor, discarding changes
Init(FEditViewName);
end;
{**
Apply changes: Compose and execute SQL
}
procedure TfrmView.btnOKClick(Sender: TObject);
procedure TfrmView.btnSaveClick(Sender: TObject);
var
sql, viewname, renamed: String;
begin
// Compose CREATE or ALTER statement
if EditViewName = '' then begin
if FEditViewName = '' then begin
sql := 'CREATE ';
viewname := editName.Text;
end else begin
sql := 'ALTER ';
viewname := EditViewName;
viewname := FEditViewName;
end;
viewname := Mainform.mask(viewname);
if rgAlgorithm.Enabled and (rgAlgorithm.ItemIndex > -1) then
@ -165,20 +160,13 @@ begin
sql := sql + 'WITH '+Uppercase(rgCheck.Items[rgCheck.ItemIndex])+' CHECK OPTION';
// Execute query and keep form open in any error case
try
Mainform.ExecUpdateQuery(sql);
// Probably rename view
if (EditViewName <> '') and (EditViewName <> editName.Text) then begin
if (FEditViewName <> '') and (FEditViewName <> editName.Text) then begin
renamed := Mainform.mask(editName.Text);
Mainform.ExecUpdateQuery('RENAME TABLE '+viewname + ' TO '+renamed);
end;
Mainform.RefreshTreeDB(Mainform.ActiveDatabase);
except
on E: THandledSQLError do begin
MessageDlg(E.Message, mtError, [mbOK], 0);
ModalResult := mrNone;
end;
end;
end;