diff --git a/components/heidisql/include/const.inc b/components/heidisql/include/const.inc
index bdc489d9..c753c741 100644
--- a/components/heidisql/include/const.inc
+++ b/components/heidisql/include/const.inc
@@ -282,11 +282,13 @@ const
// Node types of Virtual Tree nodes
NODETYPE_DEFAULT = 0;
- NODETYPE_TABLE = 1;
- NODETYPE_VIEW = 2;
- NODETYPE_DB = 3;
- NODETYPE_COLUMN = 4;
- NODETYPE_CRASHED_TABLE = 5;
+ 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;
@@ -306,3 +308,24 @@ const
MSG_COPYMAXSIZE = 'Copying data is limited to %s but more data is available. '
+ 'Only %s out of %s rows were copied.' + CRLF + CRLF
+ 'Increase the value in Tools > Preferences > Export if you need more.';
+
+ DBO_NAME = 'Name';
+ DBO_TYPE = 'Type';
+ DBO_ENGINE = 'Engine';
+ DBO_VERSION = 'Version';
+ DBO_ROWFORMAT = 'Row_format';
+ DBO_ROWS = 'Rows';
+ DBO_AVGROWLEN = 'Avg_row_length';
+ DBO_DATALEN = 'Data_length';
+ DBO_MAXDATALEN = 'Max_data_length';
+ DBO_INDEXLEN = 'Index_length';
+ DBO_DATAFREE = 'Data_free';
+ DBO_AUTOINC = 'Auto_increment';
+ DBO_CREATED = 'Create_time';
+ DBO_UPDATED = 'Update_time';
+ DBO_CHECKED = 'Check_time';
+ DBO_COLLATION = 'Collation';
+ DBO_CHECKSUM = 'Checksum';
+ DBO_CROPTIONS = 'Create_options';
+ DBO_COMMENT = 'Comment';
+
diff --git a/source/exportsql.pas b/source/exportsql.pas
index a638d925..ced84bde 100644
--- a/source/exportsql.pas
+++ b/source/exportsql.pas
@@ -167,7 +167,7 @@ begin
else if Mainform.ActiveDatabase <> '' then begin
ds := Mainform.FetchDbTableList(Mainform.ActiveDatabase);
while not ds.Eof do begin
- SelectedTables.Add(ds.Fields[0].AsWideString);
+ SelectedTables.Add(ds.FieldByName(DBO_NAME).AsWideString);
ds.Next;
end;
end;
@@ -361,17 +361,17 @@ end;
procedure TExportSQLForm.comboSelectDatabaseChange(Sender: TObject);
var
i : Integer;
- sql: WideString;
CheckThisItem: Boolean;
+ ds: TDataset;
begin
// read tables from db
checkListTables.Items.Clear;
-
- // Fetch tables from DB
- sql := 'FROM ' + MainForm.mask(comboSelectDatabase.Text);
- if Mainform.mysql_version > 50002 then sql := 'SHOW FULL TABLES ' + sql + ' WHERE table_type=''BASE TABLE'''
- else sql := 'SHOW TABLES ' + sql;
- checkListTables.Items.Text := Mainform.GetCol( sql ).Text;
+ ds := Mainform.FetchDbTableList(comboSelectDatabase.Text);
+ while not ds.Eof do begin
+ if GetDBObjectType(ds.Fields) = NODETYPE_TABLE then
+ checkListTables.Items.Add(ds.FieldByName(DBO_NAME).AsWideString);
+ ds.Next;
+ end;
// select all/some:
for i:=0 to checkListTables.Items.Count-1 do
diff --git a/source/helpers.pas b/source/helpers.pas
index 41fe3bc0..f8dc7497 100644
--- a/source/helpers.pas
+++ b/source/helpers.pas
@@ -2327,6 +2327,8 @@ end;
// Tell type of db object (table|view) by a given row from a SHOW TABLE STATUS result
function GetDBObjectType( TableStatus: TFields ): Byte;
+var
+ t: String;
begin
{**
@see http://dev.mysql.com/doc/refman/5.1/en/show-table-status.html
@@ -2337,21 +2339,28 @@ begin
"Views bla references invalid..."
}
Result := NODETYPE_TABLE;
- if (TableStatus.Count>=3) then begin
- // Result from SHOW TABLE STATUS
+ if TableStatus.FindField('Type') <> nil then begin
+ t := TableStatus.FindField('Type').AsString;
+ if t = 'BASE TABLE' then
+ Result := NODETYPE_TABLE
+ else if t = 'VIEW' then
+ Result := NODETYPE_VIEW
+ else if t = 'FUNCTION' then
+ Result := NODETYPE_FUNCTION
+ else if t = 'PROCEDURE' then
+ Result := NODETYPE_PROCEDURE;
+ end else begin
if
TableStatus[1].IsNull and // Engine column is NULL for views
TableStatus[2].IsNull and
- (Pos('VIEW', UpperCase(TableStatus.FieldByName('Comment').AsWideString)) > 0)
- then Result := NODETYPE_VIEW;
+ (Pos('VIEW', UpperCase(TableStatus.FieldByName(DBO_COMMENT).AsWideString)) > 0)
+ then Result := NODETYPE_VIEW;
if
TableStatus[1].IsNull and
TableStatus[2].IsNull and
- (Pos('MARKED AS CRASHED', UpperCase(TableStatus.FieldByName('Comment').AsWideString)) > 0)
- then Result := NODETYPE_CRASHED_TABLE;
- end else if (TableStatus.Count=2) // Result from SHOW FULL TABLES
- and (UpperCase(TableStatus[1].AsWideString) = 'VIEW') then
- Result := NODETYPE_VIEW;
+ (Pos('MARKED AS CRASHED', UpperCase(TableStatus.FieldByName(DBO_COMMENT).AsWideString)) > 0)
+ then Result := NODETYPE_CRASHED_TABLE;
+ end;
end;
diff --git a/source/insertfiles.pas b/source/insertfiles.pas
index 0d9c8b08..6c827a99 100644
--- a/source/insertfiles.pas
+++ b/source/insertfiles.pas
@@ -111,7 +111,8 @@ begin
ComboBoxTables.Items.Clear;
ds := Mainform.FetchDbTableList(ComboBoxDBs.Text);
while not ds.Eof do begin
- ComboBoxTables.Items.Add(ds.Fields[0].AsString);
+ if GetDBObjectType(ds.Fields) in [NODETYPE_TABLE, NODETYPE_VIEW] then
+ ComboBoxTables.Items.Add(ds.FieldByName(DBO_NAME).AsString);
ds.Next;
end;
if ComboBoxTables.Items.Count > 0 then
diff --git a/source/loaddata.pas b/source/loaddata.pas
index ce40a998..198b7694 100644
--- a/source/loaddata.pas
+++ b/source/loaddata.pas
@@ -149,7 +149,8 @@ begin
seltable := Mainform.SelectedTable;
ds := Mainform.FetchDbTableList(comboDatabase.Text);
while not ds.Eof do begin
- comboTable.Items.Add(ds.Fields[0].AsWideString);
+ if GetDBObjectType(ds.Fields) in [NODETYPE_TABLE, NODETYPE_VIEW] then
+ comboTable.Items.Add(ds.FieldByName(DBO_NAME).AsWideString);
count := comboTable.Items.Count-1;
if (comboDatabase.Text = seldb) and (comboTable.Items[count] = seltable) then
comboTable.ItemIndex := count;
diff --git a/source/main.dfm b/source/main.dfm
index 26865823..fb951e46 100644
--- a/source/main.dfm
+++ b/source/main.dfm
@@ -320,7 +320,7 @@ object MainForm: TMainForm
object btnDBDropTable: TToolButton
Left = 46
Top = 0
- Action = actDropTablesAndViews
+ Action = actDropDBobjects
end
object btnDBCopyTable: TToolButton
Left = 69
@@ -899,6 +899,7 @@ object MainForm: TMainForm
OnChange = ListTablesChange
OnCompareNodes = vstCompareNodes
OnDblClick = ListTablesDblClick
+ OnEditing = ListTablesEditing
OnFreeNode = vstFreeNode
OnGetText = vstGetText
OnGetImageIndex = vstGetImageIndex
@@ -1025,6 +1026,18 @@ object MainForm: TMainForm
object tabTable: TTabSheet
Caption = 'Table'
ImageIndex = 14
+ object lblSorryNoFields: TLabel
+ Left = 0
+ Top = 0
+ Width = 502
+ Height = 340
+ Align = alClient
+ Alignment = taCenter
+ Caption = 'Please use the stored routine editor to edit attributes.'
+ Layout = tlCenter
+ WordWrap = True
+ OnClick = actEditRoutineExecute
+ end
object ListColumns: TVirtualStringTree
Left = 0
Top = 0
@@ -1099,6 +1112,17 @@ object MainForm: TMainForm
object tabData: TTabSheet
Caption = 'Data'
ImageIndex = 41
+ object lblSorryNoData: TLabel
+ Left = 0
+ Top = 91
+ Width = 502
+ Height = 249
+ Align = alClient
+ Alignment = taCenter
+ Caption = 'Stored routines don'#39't provide any data you could edit here.'
+ Layout = tlCenter
+ WordWrap = True
+ end
object pnlDataTop: TPanel
Left = 0
Top = 0
@@ -1631,7 +1655,7 @@ object MainForm: TMainForm
end
object MenuDropTable: TMenuItem
Tag = 32
- Action = actDropTablesAndViews
+ Action = actDropDBobjects
end
object N4: TMenuItem
Caption = '-'
@@ -1974,13 +1998,13 @@ object MainForm: TMainForm
ShortCut = 16463
OnExecute = actLoadSQLExecute
end
- object actDropTablesAndViews: TAction
+ object actDropDBobjects: TAction
Category = 'Database'
- Caption = 'Drop table/view ...'
+ Caption = 'Drop ...'
Enabled = False
- Hint = 'Deletes tables and/or views'
+ Hint = 'Deletes tables, views, procedures and functions'
ImageIndex = 16
- OnExecute = actDropTablesAndViewsExecute
+ OnExecute = actDropDBobjectsExecute
end
object actEditView: TAction
Category = 'Database'
@@ -2425,6 +2449,13 @@ object MainForm: TMainForm
ImageIndex = 119
OnExecute = actCreateRoutineExecute
end
+ object actEditRoutine: TAction
+ Category = 'Database'
+ Caption = 'Edit stored routine ...'
+ Hint = 'Edit stored procedure or function'
+ ImageIndex = 119
+ OnExecute = actEditRoutineExecute
+ end
end
object SaveDialog2: TSaveDialog
DefaultExt = 'reg'
@@ -5933,7 +5964,13 @@ object MainForm: TMainForm
Action = actEditView
end
object PopupMenuDropTable: TMenuItem
- Action = actDropTablesAndViews
+ Action = actDropDBobjects
+ end
+ object menuTreeCreateRoutine: TMenuItem
+ Action = actCreateRoutine
+ end
+ object menuTreeEditRoutine: TMenuItem
+ Action = actEditRoutine
end
object Exporttables2: TMenuItem
Action = actExportTables
@@ -5977,6 +6014,9 @@ object MainForm: TMainForm
object menuEditView: TMenuItem
Action = actEditView
end
+ object menuEditRoutine: TMenuItem
+ Action = actEditRoutine
+ end
object InsertfilesintoBLOBfields1a: TMenuItem
Action = actInsertFiles
end
@@ -5984,7 +6024,7 @@ object MainForm: TMainForm
Caption = '-'
end
object menudroptablea: TMenuItem
- Action = actDropTablesAndViews
+ Action = actDropDBobjects
end
object menuemptytable: TMenuItem
Action = actEmptyTables
diff --git a/source/main.pas b/source/main.pas
index 4e5fcd00..462d913f 100644
--- a/source/main.pas
+++ b/source/main.pas
@@ -113,7 +113,7 @@ type
actInsertFiles: TAction;
InsertfilesintoBLOBfields1: TMenuItem;
actExportTables: TAction;
- actDropTablesAndViews: TAction;
+ actDropDBobjects: TAction;
actLoadSQL: TAction;
ImportSQL1: TMenuItem;
menuConnections: TPopupMenu;
@@ -460,6 +460,12 @@ type
actCreateRoutine1: TMenuItem;
btnDBCreateRoutine: TToolButton;
btnExit: TToolButton;
+ actEditRoutine: TAction;
+ menuTreeEditRoutine: TMenuItem;
+ menuTreeCreateRoutine: TMenuItem;
+ menuEditRoutine: TMenuItem;
+ lblSorryNoFields: TLabel;
+ lblSorryNoData: TLabel;
procedure refreshMonitorConfig;
procedure loadWindowConfig;
procedure saveWindowConfig;
@@ -508,7 +514,7 @@ type
procedure actDataPostChangesExecute(Sender: TObject);
procedure actDropDatabaseExecute(Sender: TObject);
procedure actDropFieldsExecute(Sender: TObject);
- procedure actDropTablesAndViewsExecute(Sender: TObject);
+ procedure actDropDBobjectsExecute(Sender: TObject);
procedure actEditDatabaseExecute(Sender: TObject);
procedure actEditIndexesExecute(Sender: TObject);
procedure actEmptyTablesExecute(Sender: TObject);
@@ -733,6 +739,9 @@ type
procedure EnumerateRecentFilters;
procedure LoadRecentFilter(Sender: TObject);
procedure actCreateRoutineExecute(Sender: TObject);
+ procedure actEditRoutineExecute(Sender: TObject);
+ procedure ListTablesEditing(Sender: TBaseVirtualTree; Node: PVirtualNode;
+ Column: TColumnIndex; var Allowed: Boolean);
private
FDelimiter: String;
ServerUptime : Integer;
@@ -759,6 +768,7 @@ type
DataGridDB, DataGridTable : WideString;
PrevTableColWidths : WideStrings.TWideStringList;
DataGridHasChanges : Boolean;
+ InformationSchemaTables : TWideStringlist;
function GetParamValue(const paramChar: Char; const paramName:
string; var curIdx: Byte; out paramValue: string): Boolean;
procedure SetDelimiter(Value: String);
@@ -1750,6 +1760,7 @@ begin
ClearAllTableLists;
FreeAndNil(DatabasesWanted);
FreeAndNil(Databases);
+ FreeAndNil(InformationSchemaTables);
// Closing connection
if Assigned(FMysqlConn) then begin
@@ -1934,7 +1945,7 @@ begin
// "Edit view" was clicked in DBTree's context menu
ds := FetchDbTableList(ActiveDatabase);
ds.RecNo := DBtree.GetFirstSelected.Index+1;
- ViewForm.EditViewName := ds.Fields[0].AsString;
+ ViewForm.EditViewName := ds.FieldByName(DBO_NAME).AsString;
end else
// If we're here, there's a menu item "Edit/Create view" in an unknown location
raise Exception.Create('Internal error in actCreateViewExexute.');
@@ -2328,11 +2339,34 @@ begin
end;
// Drop Table(s)
-procedure TMainForm.actDropTablesAndViewsExecute(Sender: TObject);
+procedure TMainForm.actDropDBobjectsExecute(Sender: TObject);
var
- i : Integer;
- Tables, Views : TWideStringList;
- msg, sql, activeDB : String;
+ AllCount : Integer;
+ Tables, Views, Functions, Procedures: TWideStringList;
+ msg, activeDB : String;
+
+ procedure DoDrop(Kind: String; List: TWideStringlist; MultiDrops: Boolean);
+ var
+ i: Integer;
+ baseSql, sql: WideString;
+ begin
+ if List.Count > 0 then begin
+ baseSql := 'DROP '+Kind+' ';
+ sql := '';
+ for i := 0 to List.Count - 1 do begin
+ if (i > 0) and MultiDrops then sql := sql + ', ';
+ sql := sql + mask(List[i]);
+ if not MultiDrops then begin
+ ExecUpdateQuery(baseSql + sql);
+ sql := '';
+ end;
+ end;
+ if MultiDrops then
+ ExecUpdateQuery(baseSql + sql);
+ end;
+ FreeAndNil(List);
+ end;
+
begin
debug('drop table activated');
// Set default database name to to ActiveDatabase.
@@ -2341,61 +2375,50 @@ begin
Tables := TWideStringlist.Create;
Views := TWideStringlist.Create;
+ Procedures := TWideStringlist.Create;
+ Functions := TWideStringlist.Create;
if (PageControlMain.ActivePage = tabDatabase) and
((Sender as TAction).ActionComponent <> PopupMenuDropTable) then begin
// Invoked from one of the various buttons, SheetDatabase is the active page, drop highlighted table(s).
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);
end else begin
// Invoked from one of the various buttons, drop table selected in tree view.
case GetSelectedNodeType of
- NODETYPE_TABLE: Tables.Add(SelectedTable);
- NODETYPE_CRASHED_TABLE: Tables.Add(SelectedTable);
- NODETYPE_VIEW: Views.Add(SelectedTable)
+ NODETYPE_TABLE, NODETYPE_CRASHED_TABLE: Tables.Add(SelectedTable);
+ NODETYPE_VIEW: Views.Add(SelectedTable);
+ NODETYPE_PROCEDURE: Procedures.Add(SelectedTable);
+ NODETYPE_FUNCTION: Functions.Add(SelectedTable);
end;
end;
// Fix actions temporarily enabled for popup menu.
ValidateControls;
+ AllCount := Tables.Count + Views.Count + Procedures.Count + Functions.Count;
+
// Safety stop to avoid firing DROP TABLE without tablenames
- if (Tables.Count = 0) and (Views.Count = 0) then
+ if (AllCount = 0) then
Exit;
// Ask user for confirmation to drop selected objects
- msg := 'Drop ' + IntToStr(Tables.Count+Views.Count) + ' table(s) and/or view(s) in database "'+activeDB+'"?'
+ msg := 'Drop ' + IntToStr(AllCount) + ' object(s) in database "'+activeDB+'"?'
+ CRLF;
- if Tables.Count > 0 then msg := msg + CRLF + 'Tables: ' + ImplodeStr(', ', Tables);
- if Views.Count > 0 then msg := msg + CRLF + 'Views: ' + ImplodeStr(', ', Views);
+ if Tables.Count > 0 then msg := msg + CRLF + 'Table(s): ' + ImplodeStr(', ', Tables);
+ if Views.Count > 0 then msg := msg + CRLF + 'View(s): ' + ImplodeStr(', ', Views);
+ if Procedures.Count > 0 then msg := msg + CRLF + 'Procedure(s): ' + ImplodeStr(', ', Procedures);
+ if Functions.Count > 0 then msg := msg + CRLF + 'Function(s): ' + ImplodeStr(', ', Functions);
if MessageDlg(msg, mtConfirmation, [mbok,mbcancel], 0) <> mrok then
Exit;
- // Compose and run DROP TABLE query
- if Tables.Count > 0 then begin
- sql := 'DROP TABLE ';
- for i := 0 to Tables.Count - 1 do
- begin
- if i > 0 then
- sql := sql + ', ';
- sql := sql + mask(Tables[i]);
- end;
- ExecUpdateQuery( sql );
- end;
- FreeAndNil(Tables);
-
- // Compose and run DROP VIEW query
- if Views.Count > 0 then begin
- sql := 'DROP VIEW ';
- for i := 0 to Views.Count - 1 do
- begin
- if i > 0 then
- sql := sql + ', ';
- sql := sql + mask(Views[i]);
- end;
- ExecUpdateQuery( sql );
- end;
- FreeAndNil(Views);
+ // Compose and run DROP [TABLE|VIEW|...] queries
+ DoDrop('TABLE', Tables, True);
+ DoDrop('VIEW', Views, True);
+ DoDrop('PROCEDURE', Procedures, False);
+ DoDrop('FUNCTION', Functions, False);
// Refresh ListTables + dbtree so the dropped tables are gone:
actRefresh.Execute;
@@ -2673,10 +2696,18 @@ var
NodeData: PVTreeData;
begin
// table-doubleclick
- if Assigned(ListTables.FocusedNode) then begin
- NodeData := ListTables.GetNodeData(ListTables.FocusedNode);
- SelectedTable := NodeData.Captions[0];
- PageControlMain.ActivePage := tabTable;
+ if not Assigned(ListTables.FocusedNode) then
+ Exit;
+
+ NodeData := ListTables.GetNodeData(ListTables.FocusedNode);
+ case NodeData.ImageIndex of
+ ICONINDEX_TABLE, ICONINDEX_CRASHED_TABLE, ICONINDEX_VIEW: begin
+ SelectedTable := NodeData.Captions[0];
+ PageControlMain.ActivePage := tabTable;
+ end;
+ ICONINDEX_STOREDPROCEDURE, ICONINDEX_STOREDFUNCTION: begin
+ actEditRoutine.Execute;
+ end;
end;
end;
@@ -3578,14 +3609,25 @@ begin
if DataGridHasChanges then
actDataPostChangesExecute(Sender);
+ // Ensure
and are visible
+ tabTable.TabVisible := true;
+ tabData.TabVisible := true;
+ // Switch to
+ PageControlMain.ActivePage := tabData;
+ if not (GetSelectedNodeType in [NODETYPE_TABLE, NODETYPE_CRASHED_TABLE, NODETYPE_VIEW]) then begin
+ DataGrid.Hide; // Reveals lblSorryNoData
+ pnlDataTop.Hide;
+ pnlFilter.Hide;
+ Screen.Cursor := crDefault;
+ Exit;
+ end else begin
+ DataGrid.Show;
+ pnlFilter.Show;
+ pnlDataTop.Show;
+ end;
+
try
if (SelectedTable <> '') and (ActiveDatabase <> '') then begin
- // Ensure and are visible
- tabTable.TabVisible := true;
- tabData.TabVisible := true;
- // Switch to
- PageControlMain.ActivePage := tabData;
-
if FDataGridSelect = nil then
FDataGridSelect := WideStrings.TWideStringlist.Create;
if DataGridTable <> SelectedTable then begin
@@ -3776,8 +3818,8 @@ begin
rows_total := -1;
IsInnodb := False;
for i := 0 to ds.RecordCount - 1 do begin
- if ds.Fields[0].AsWideString = SelectedTable then begin
- rows_total := MakeInt(ds.FieldByName('Rows').AsString);
+ if ds.FieldByName(DBO_NAME).AsWideString = SelectedTable then begin
+ rows_total := MakeInt(ds.FieldByName(DBO_ROWS).AsString);
IsInnodb := ds.Fields[1].AsString = 'InnoDB';
break;
end;
@@ -3842,10 +3884,11 @@ begin
// Do this only if the user clicked the new tab. Not on automatic tab changes.
if Sender = PageControlMain then begin
if tab = tabDatabase then ListTables.SetFocus
- else if tab = tabTable then ListColumns.SetFocus
+ else if (tab = tabTable) and (ListColumns.Visible) then ListColumns.SetFocus
else if tab = tabData then begin
viewdata(Sender);
- DataGrid.SetFocus;
+ if DataGrid.Visible then
+ DataGrid.SetFocus;
end else if tab = tabQuery then SynMemoQuery.SetFocus;
end;
@@ -3888,6 +3931,8 @@ function TMainForm.FetchDbTableList(db: WideString): TDataSet;
var
ds: TDataSet;
OldCursor: TCursor;
+ Unions: TWideStringlist;
+ ListObjectsSQL: WideString;
begin
if not DbTableListCached(db) then begin
// Not in cache, load table list.
@@ -3895,12 +3940,74 @@ begin
Screen.Cursor := crHourGlass;
ShowStatus('Fetching tables from "' + db + '" ...');
try
- ds := GetResults('SHOW TABLE STATUS FROM ' + mask(db), false, false);
+ if not Assigned(InformationSchemaTables) then
+ InformationSchemaTables := GetCol('SHOW TABLES FROM '+mask(DBNAME_INFORMATION_SCHEMA), 0, True, False);
+ if InformationSchemaTables.IndexOf('TABLES') > -1 then begin
+ Unions := TWideStringlist.Create;
+
+ // Tables and (system) views
+ Unions.Add('SELECT TABLE_NAME AS '+mask(DBO_NAME)+
+ ', TABLE_TYPE AS '+mask(DBO_TYPE)+
+ ', ENGINE AS '+mask(DBO_ENGINE)+
+ ', VERSION AS '+mask(DBO_VERSION)+
+ ', ROW_FORMAT AS '+mask(DBO_ROWFORMAT)+
+ ', TABLE_ROWS AS '+mask(DBO_ROWS)+
+ ', AVG_ROW_LENGTH AS '+mask(DBO_AVGROWLEN)+
+ ', DATA_LENGTH AS '+mask(DBO_DATALEN)+
+ ', MAX_DATA_LENGTH AS '+mask(DBO_MAXDATALEN)+
+ ', INDEX_LENGTH AS '+mask(DBO_INDEXLEN)+
+ ', DATA_FREE AS '+mask(DBO_DATAFREE)+
+ ', AUTO_INCREMENT AS '+mask(DBO_AUTOINC)+
+ ', CREATE_TIME AS '+mask(DBO_CREATED)+
+ ', UPDATE_TIME AS '+mask(DBO_UPDATED)+
+ ', CHECK_TIME AS '+mask(DBO_CHECKED)+
+ ', TABLE_COLLATION AS '+mask(DBO_COLLATION)+
+ ', CHECKSUM AS '+mask(DBO_CHECKSUM)+
+ ', CREATE_OPTIONS AS '+mask(DBO_CROPTIONS)+
+ ', TABLE_COMMENT AS '+mask(DBO_COMMENT)+
+ ' FROM '+mask(DBNAME_INFORMATION_SCHEMA)+'.TABLES ' +
+ 'WHERE TABLE_SCHEMA = '+esc(db));
+
+ // Stored routines
+ if InformationSchemaTables.IndexOf('ROUTINES') > -1 then begin
+ Unions.Add('SELECT ROUTINE_NAME AS '+mask(DBO_NAME)+
+ ', ROUTINE_TYPE AS '+mask(DBO_TYPE)+
+ ', NULL AS '+mask(DBO_ENGINE)+
+ ', NULL AS '+mask(DBO_VERSION)+
+ ', NULL AS '+mask(DBO_ROWFORMAT)+
+ ', NULL AS '+mask(DBO_ROWS)+
+ ', NULL AS '+mask(DBO_AVGROWLEN)+
+ ', NULL AS '+mask(DBO_DATALEN)+
+ ', NULL AS '+mask(DBO_MAXDATALEN)+
+ ', NULL AS '+mask(DBO_INDEXLEN)+
+ ', NULL AS '+mask(DBO_DATAFREE)+
+ ', NULL AS '+mask(DBO_AUTOINC)+
+ ', CREATED AS '+mask(DBO_CREATED)+
+ ', LAST_ALTERED AS '+mask(DBO_UPDATED)+
+ ', NULL AS '+mask(DBO_CHECKED)+
+ ', NULL AS '+mask(DBO_COLLATION)+
+ ', NULL AS '+mask(DBO_CHECKSUM)+
+ ', NULL AS '+mask(DBO_CROPTIONS)+
+ ', ROUTINE_COMMENT AS '+mask(DBO_COMMENT)+
+ ' FROM '+mask(DBNAME_INFORMATION_SCHEMA)+'.ROUTINES ' +
+ 'WHERE ROUTINE_SCHEMA = '+esc(db));
+ end;
+ if Unions.Count = 1 then
+ ListObjectsSQL := Unions[0]
+ else
+ ListObjectsSQL := '(' + implodestr(') UNION (', Unions) + ')';
+ ListObjectsSQL := ListObjectsSQL + ' ORDER BY `Name`';
+ FreeAndNil(Unions);
+ end else begin
+ // For servers lacking the INFORMATION_SCHEMA or the TABLES table
+ ListObjectsSQL := 'SHOW TABLE STATUS FROM ' + mask(db);
+ end;
+ ds := GetResults(ListObjectsSQL);
CachedTableLists.AddObject(db, ds);
// Add table names to SQL highlighter
SynSQLSyn1.TableNames.BeginUpdate;
while not ds.Eof do begin
- SynSQLSyn1.TableNames.Add(ds.Fields[0].AsWideString);
+ SynSQLSyn1.TableNames.Add(ds.FieldByName(DBO_NAME).AsWideString);
ds.Next;
end;
SynSQLSyn1.TableNames.EndUpdate;
@@ -3977,7 +4084,7 @@ var
i : Integer;
bytes : Int64;
ds : TDataSet;
- ListCaptions,
+ Cap,
SelectedCaptions: WideStrings.TWideStringList;
begin
// DB-Properties
@@ -3986,145 +4093,89 @@ begin
// Remember selected nodes
SelectedCaptions := GetVTCaptions(ListTables, True);
- try
- ds := FetchDbTableList(db);
- ShowStatus( 'Displaying tables from "' + db + '" ...' );
+ ds := FetchDbTableList(db);
+ ShowStatus( 'Displaying tables from "' + db + '" ...' );
- ListTables.BeginUpdate;
- ListTables.Clear;
+ ListTables.BeginUpdate;
+ ListTables.Clear;
- SetLength(VTRowDataListTables, ds.RecordCount);
- for i := 1 to ds.RecordCount do
- begin
- listcaptions := WideStrings.TWideStringList.Create;
- // Table
- ListCaptions.Add( ds.Fields[0].AsWideString );
+ SetLength(VTRowDataListTables, ds.RecordCount);
+ for i := 1 to ds.RecordCount do
+ begin
+ VTRowDataListTables[i-1].Captions := WideStrings.TWideStringList.Create;
+ Cap := VTRowDataListTables[i-1].Captions;
+ // Object name
+ Cap.Add( FieldContent(ds, DBO_NAME) );
+ if (FieldContent(ds, DBO_ROWS) <> '') then
+ Cap.Add( FormatNumber( FieldContent(ds, DBO_ROWS) ) )
+ else Cap.Add('');
+ // Size: Data_length + Index_length
+ bytes := GetTableSize(ds);
+ if bytes >= 0 then Cap.Add(FormatByteNumber(bytes))
+ else Cap.Add('');
+ Cap.Add( FieldContent(ds, DBO_CREATED) );
+ Cap.Add( FieldContent(ds, DBO_UPDATED) );
+ Cap.Add( FieldContent(ds, DBO_ENGINE) );
+ Cap.Add( FieldContent(ds, DBO_COMMENT) );
+ Cap.Add( FieldContent(ds, DBO_VERSION) );
+ Cap.Add( FieldContent(ds, DBO_ROWFORMAT) );
+ if (FieldContent(ds, DBO_AVGROWLEN) <> '') then
+ Cap.Add( FormatByteNumber(FieldContent(ds, DBO_AVGROWLEN)) )
+ else Cap.Add('');
+ if (FieldContent(ds, DBO_MAXDATALEN) <> '') then
+ Cap.Add( FormatByteNumber(FieldContent(ds, DBO_MAXDATALEN)) )
+ else Cap.Add('');
+ if (FieldContent(ds, DBO_INDEXLEN) <> '') then
+ Cap.Add( FormatByteNumber(FieldContent(ds, DBO_INDEXLEN)) )
+ else Cap.Add('');
+ if (FieldContent(ds, DBO_DATAFREE) <> '') then
+ Cap.Add( FormatByteNumber(FieldContent(ds, DBO_DATAFREE)) )
+ else Cap.Add('');
+ if (FieldContent(ds, DBO_AUTOINC) <> '') then
+ Cap.Add( FormatNumber(FieldContent(ds, DBO_AUTOINC)) )
+ else Cap.Add('');
+ Cap.Add( FieldContent(ds, DBO_AUTOINC) );
+ Cap.Add( FieldContent(ds, DBO_COLLATION) );
+ Cap.Add( FieldContent(ds, DBO_CHECKSUM) );
+ Cap.Add( FieldContent(ds, DBO_CROPTIONS) );
+ if ds.FindField(DBO_TYPE) <> nil then
+ Cap.Add(FieldContent(ds, DBO_TYPE))
+ else
+ Cap.Add('BASE TABLE');
- // Treat tables slightly different than views
- case GetDBObjectType( ds.Fields) of
- NODETYPE_TABLE, NODETYPE_CRASHED_TABLE: // A normal table
- begin
- if GetDBObjectType(ds.Fields) = NODETYPE_CRASHED_TABLE then begin
- VTRowDataListTables[i-1].ImageIndex := ICONINDEX_CRASHED_TABLE;
- VTRowDataListTables[i-1].NodeType := NODETYPE_CRASHED_TABLE;
- end else begin
- VTRowDataListTables[i-1].ImageIndex := ICONINDEX_TABLE;
- VTRowDataListTables[i-1].NodeType := NODETYPE_TABLE;
- end;
- // Rows
- if ds.FindField('Rows') <> nil then
- ListCaptions.Add( FormatNumber( FieldContent(ds, 'Rows') ) )
- else
- ListCaptions.Add('');
- // Size: Data_length + Index_length
- bytes := GetTableSize(ds);
- if bytes >= 0 then ListCaptions.Add(FormatByteNumber(bytes))
- else ListCaptions.Add('');
- // Created:
- ListCaptions.Add( FieldContent(ds, 'Create_time') );
- // Updated:
- ListCaptions.Add( FieldContent(ds, 'Update_time') );
- // Engine
- if ds.FindField('Type') <> nil then
- ListCaptions.Add( FieldContent(ds, 'Type') )
- else
- ListCaptions.Add( FieldContent(ds, 'Engine') );
- // Comment
- ListCaptions.Add( FieldContent(ds, 'Comment') );
- // Version
- ListCaptions.Add( FieldContent(ds, 'Version') );
- // Row format
- ListCaptions.Add( FieldContent(ds, 'Row_format') );
- // Avg row length
- if (FieldContent(ds, 'Avg_row_length') <> '') then
- ListCaptions.Add( FormatByteNumber(FieldContent(ds, 'Avg_row_length')) )
- else ListCaptions.Add('');
- // Max data length
- if (FieldContent(ds, 'Max_data_length') <> '') then
- ListCaptions.Add( FormatByteNumber(FieldContent(ds, 'Max_data_length')) )
- else ListCaptions.Add('');
- // Index length
- if (FieldContent(ds, 'Index_length') <> '') then
- ListCaptions.Add( FormatByteNumber(FieldContent(ds, 'Index_length')) )
- else ListCaptions.Add('');
- // Data free
- if (FieldContent(ds, 'Data_free') <> '') then
- ListCaptions.Add( FormatByteNumber(FieldContent(ds, 'Data_free')) )
- else ListCaptions.Add('');
- // Auto increment
- if (FieldContent(ds, 'Auto_increment') <> '') then
- ListCaptions.Add( FormatNumber(FieldContent(ds, 'Auto_increment')) )
- else ListCaptions.Add('');
- // Check time
- ListCaptions.Add( FieldContent(ds, 'Check_time') );
- // Collation
- ListCaptions.Add( FieldContent(ds, 'Collation') );
- // Checksum
- ListCaptions.Add( FieldContent(ds, 'Checksum') );
- // Create_options
- ListCaptions.Add( FieldContent(ds, 'Create_options') );
- // Object type
- ListCaptions.Add('Base table');
- end;
-
- NODETYPE_VIEW:
- begin // View
- VTRowDataListTables[i-1].ImageIndex := ICONINDEX_VIEW;
- VTRowDataListTables[i-1].NodeType := NODETYPE_VIEW;
- // Rows
- ListCaptions.Add('');
- // Size
- ListCaptions.Add('');
- // Created:
- ListCaptions.Add('');
- // Updated:
- ListCaptions.Add('');
- // Engine
- ListCaptions.Add('');
- // Comment
- ListCaptions.Add(FieldContent(ds, 'Comment'));
- // Version
- ListCaptions.Add('');
- // Row_format
- ListCaptions.Add('');
- // Avg_row_length
- ListCaptions.Add('');
- // Max_data_length
- ListCaptions.Add('');
- // Index_length
- ListCaptions.Add('');
- // Data_free
- ListCaptions.Add('');
- // Auto_increment
- ListCaptions.Add('');
- // Check_time
- ListCaptions.Add('');
- // Collation
- ListCaptions.Add('');
- // Checksum
- ListCaptions.Add('');
- // Create_options
- ListCaptions.Add('');
- // Object Type
- ListCaptions.Add('View');
- end;
+ VTRowDataListTables[i-1].NodeType := GetDBObjectType( ds.Fields);
+ // Find icon
+ case VTRowDataListTables[i-1].NodeType of
+ NODETYPE_TABLE, NODETYPE_CRASHED_TABLE: // A normal table
+ begin
+ if GetDBObjectType(ds.Fields) = NODETYPE_CRASHED_TABLE then
+ VTRowDataListTables[i-1].ImageIndex := ICONINDEX_CRASHED_TABLE
+ else
+ VTRowDataListTables[i-1].ImageIndex := ICONINDEX_TABLE;
end;
- VTRowDataListTables[i-1].Captions := ListCaptions;
- ds.Next;
+ NODETYPE_VIEW:
+ VTRowDataListTables[i-1].ImageIndex := ICONINDEX_VIEW;
+
+ NODETYPE_PROCEDURE:
+ VTRowDataListTables[i-1].ImageIndex := ICONINDEX_STOREDPROCEDURE;
+
+ NODETYPE_FUNCTION:
+ VTRowDataListTables[i-1].ImageIndex := ICONINDEX_STOREDFUNCTION;
end;
- finally
- ListTables.RootNodeCount := Length(VTRowDataListTables);
- ListTables.EndUpdate;
- SetVTSelection(ListTables, SelectedCaptions);
- showstatus(db + ': ' + IntToStr(ListTables.RootNodeCount) +' table(s)', 0);
- tabDatabase.Caption := sstr('Database: ' + db, 30);
- ShowStatus(STATUS_MSG_READY);
- Screen.Cursor := crDefault;
- // Ensure tree db node displays its chidren initialized
- DBtree.ReinitChildren(FindDBNode(db), False);
- ValidateControls;
+
+ ds.Next;
end;
+ ListTables.RootNodeCount := Length(VTRowDataListTables);
+ ListTables.EndUpdate;
+ SetVTSelection(ListTables, SelectedCaptions);
+ showstatus(db + ': ' + IntToStr(ListTables.RootNodeCount) +' table(s)', 0);
+ tabDatabase.Caption := sstr('Database: ' + db, 30);
+ ShowStatus(STATUS_MSG_READY);
+ Screen.Cursor := crDefault;
+ // Ensure tree db node displays its chidren initialized
+ DBtree.ReinitChildren(FindDBNode(db), False);
+ ValidateControls;
end;
@@ -4145,13 +4196,31 @@ var
dummy: Boolean;
hasCommentColumn: Boolean;
SelectedCaptions: WideStrings.TWideStringList;
- defaultVal: WideString;
+ defaultVal, cap: WideString;
begin
// Table-Properties
dataselected := false;
Screen.Cursor := crHourGlass;
- tabTable.Caption := sstr('Table: ' + SelectedTable, 30);
+ case GetSelectedNodeType of
+ NODETYPE_TABLE, NODETYPE_CRASHED_TABLE: begin
+ cap := 'Table';
+ tabTable.ImageIndex := ICONINDEX_TABLE;
+ end;
+ NODETYPE_VIEW: begin
+ cap := 'View';
+ tabTable.ImageIndex := ICONINDEX_VIEW;
+ end;
+ NODETYPE_PROCEDURE: begin
+ cap := 'Procedure';
+ tabTable.ImageIndex := ICONINDEX_STOREDPROCEDURE;
+ end;
+ NODETYPE_FUNCTION: begin
+ cap := 'Function';
+ tabTable.ImageIndex := ICONINDEX_STOREDFUNCTION;
+ end;
+ end;
+ tabTable.Caption := sstr(cap+': ' + SelectedTable, 30);
tabDatabase.TabVisible := true;
tabTable.TabVisible := true;
@@ -4162,6 +4231,13 @@ begin
(PageControlMain.ActivePage = tabDatabase)
) then PageControlMain.ActivePage := tabTable;
+ if not (GetSelectedNodeType in [NODETYPE_TABLE, NODETYPE_CRASHED_TABLE, NODETYPE_VIEW]) then begin
+ ListColumns.Hide; // Reveals lblSorryNoFields
+ Screen.Cursor := crDefault;
+ Exit;
+ end else
+ ListColumns.Show;
+
ShowStatus( 'Reading table properties...' );
// Remember selected nodes
SelectedCaptions := GetVTCaptions(ListColumns, True);
@@ -4334,7 +4410,7 @@ end;
}
procedure TMainForm.ValidateControls( FrmIsFocussed: Boolean = true );
var
- DBObjectSelected, TableSelected, ViewSelected,
+ DBObjectSelected, TableSelected, ViewSelected, RoutineSelected,
inDbTab, inTableTab, inDataTab, inQueryTab, inDataOrQueryTab, inDataOrQueryTabNotEmpty,
FieldsSelected, FieldFocused, dummy, DBfocused : Boolean;
NodeData: PVTreeData;
@@ -4351,12 +4427,14 @@ begin
DBObjectSelected := (Length(SelectedNodes)>0) and FrmIsFocussed;
TableSelected := False;
ViewSelected := False;
+ RoutineSelected := False;
// Check type of first selected node, to en-/disable certain menu items
if DBObjectSelected then begin
NodeData := ListTables.GetNodeData( SelectedNodes[0] );
TableSelected := (NodeData.NodeType = NODETYPE_TABLE) or (NodeData.NodeType = NODETYPE_CRASHED_TABLE);
ViewSelected := NodeData.NodeType = NODETYPE_VIEW;
+ RoutineSelected := NodeData.NodeType in [NODETYPE_PROCEDURE, NODETYPE_FUNCTION];
end;
// Standard toolbar and main menu
@@ -4380,9 +4458,10 @@ begin
// Database tab
actEmptyTables.Enabled := inDbTab and TableSelected;
actEditTableProperties.Enabled := inDbTab and TableSelected;
- MenuRenameTable.Enabled := inDbTab and DBObjectSelected;
- actCopyTable.Enabled := inDbTab and DBObjectSelected;
+ MenuRenameTable.Enabled := inDbTab and (TableSelected or ViewSelected);
+ actCopyTable.Enabled := inDbTab and (TableSelected or ViewSelected);
actEditView.Enabled := inDbTab and ViewSelected and (mysql_version >= 50001);
+ actEditRoutine.Enabled := inDbTab and RoutineSelected and (mysql_version >= 50003);
actCreateView.Enabled := FrmIsFocussed and (ActiveDatabase <> '') and (mysql_version >= 50001);
actCreateRoutine.Enabled := FrmIsFocussed and (ActiveDatabase <> '') and (mysql_version >= 50003);
actCreateDatabase.Enabled := FrmIsFocussed;
@@ -4393,7 +4472,7 @@ begin
actEditDatabase.Hint := STR_NOTSUPPORTED
else
actEditDatabase.Hint := 'Rename and/or modify character set of database';
- actDropTablesAndViews.Enabled := (DBObjectSelected and inDbTab) or ((not inQueryTab) and (SelectedTable <> '') and FrmIsFocussed);
+ actDropDBobjects.Enabled := (DBObjectSelected and inDbTab) or ((not inQueryTab) and (SelectedTable <> '') and FrmIsFocussed);
actCreateTable.Enabled := (ActiveDatabase <> '') and FrmIsFocussed;
actEditTableFields.Enabled := DBObjectSelected and inDbTab;
@@ -4932,6 +5011,17 @@ begin
end;
+procedure TMainForm.ListTablesEditing(Sender: TBaseVirtualTree;
+ Node: PVirtualNode; Column: TColumnIndex; var Allowed: Boolean);
+var
+ NodeData: PVTreeData;
+begin
+ // Tables and views can be renamed, routines cannot
+ NodeData := Sender.GetNodeData(Node);
+ Allowed := NodeData.ImageIndex in [ICONINDEX_TABLE, ICONINDEX_VIEW];
+end;
+
+
{***
Rename table after checking the new name for invalid characters
}
@@ -5257,9 +5347,11 @@ begin
L := DBtree.GetNodeLevel(DBtree.GetFirstSelected);
actCreateTable.Enabled := L in [1,2];
actCreateView.Enabled := (L in [1,2]) and (mysql_version >= 50001);
+ actCreateRoutine.Enabled := (L in [1,2]) and (mysql_version >= 50003);
actEditTableProperties.Enabled := (L = 2) and ((GetSelectedNodeType = NODETYPE_TABLE) or (GetSelectedNodeType = NODETYPE_CRASHED_TABLE));
actEditView.Enabled := (L = 2) and (GetSelectedNodeType = NODETYPE_VIEW);
- actDropTablesAndViews.Enabled := (L = 2);
+ actEditRoutine.Enabled := (L = 2) and (GetSelectedNodeType in [NODETYPE_PROCEDURE, NODETYPE_FUNCTION]);
+ actDropDBobjects.Enabled := (L = 2);
end;
@@ -6940,7 +7032,7 @@ begin
2: begin
ds := FetchDbTableList(Databases[Node.Parent.Index]);
ds.RecNo := Node.Index+1;
- CellText := ds.Fields[0].AsWideString;
+ CellText := ds.FieldByName(DBO_NAME).AsWideString;
end;
end;
1: case GetNodeType(Node) of
@@ -7032,6 +7124,10 @@ begin
if Kind = ikSelected then
ImageIndex := ICONINDEX_CRASHED_TABLE_HIGHLIGHT
else ImageIndex := ICONINDEX_CRASHED_TABLE;
+ NODETYPE_PROCEDURE:
+ ImageIndex := ICONINDEX_STOREDPROCEDURE;
+ NODETYPE_FUNCTION:
+ ImageIndex := ICONINDEX_STOREDFUNCTION;
end;
end;
end;
@@ -9024,5 +9120,22 @@ begin
end;
+procedure TMainForm.actEditRoutineExecute(Sender: TObject);
+var
+ NodeData: PVTreeData;
+begin
+ if not Assigned(RoutineEditForm) then
+ RoutineEditForm := TfrmRoutineEditor.Create(Self);
+
+ if ListTables.Focused then begin
+ NodeData := ListTables.GetNodeData( ListTables.FocusedNode );
+ RoutineEditForm.AlterRoutineName := NodeData.Captions[0];
+ end else
+ RoutineEditForm.AlterRoutineName := SelectedTable;
+
+ RoutineEditForm.ShowModal;
+end;
+
+
end.
diff --git a/source/optimizetables.pas b/source/optimizetables.pas
index df12dcdf..9d62de9d 100644
--- a/source/optimizetables.pas
+++ b/source/optimizetables.pas
@@ -121,7 +121,8 @@ begin
ds := Mainform.FetchDbTableList(DBComboBox.Text);
TablesCheckListBox.Items.Clear;
while not ds.Eof do begin
- TablesCheckListBox.Items.Add(ds.Fields[0].AsWideString);
+ if GetDBObjectType(ds.Fields) = NODETYPE_TABLE then
+ TablesCheckListBox.Items.Add(ds.FieldByName(DBO_NAME).AsWideString);
ds.Next;
end;
// Check all
diff --git a/source/selectdbobject.pas b/source/selectdbobject.pas
index 33fa7c90..6f4f050e 100644
--- a/source/selectdbobject.pas
+++ b/source/selectdbobject.pas
@@ -206,7 +206,7 @@ begin
ds.RecNo := Node.Index+1;
cols := Mainform.GetCol('SHOW COLUMNS FROM '
+ Mainform.mask(Mainform.Databases[Node.Parent.Index])+'.'
- + Mainform.Mask(ds.Fields[0].AsWideString));
+ + Mainform.Mask(ds.FieldByName(DBO_NAME).AsWideString));
FColumns[Node.Parent.Index][Node.Index] := cols;
ChildCount := cols.Count;
end;
@@ -226,7 +226,7 @@ begin
1: begin
ds := Mainform.FetchDbTableList(Mainform.Databases[Node.Parent.Index]);
ds.RecNo := Node.Index+1;
- CellText := ds.Fields[0].AsWideString;
+ CellText := ds.FieldByName(DBO_NAME).AsWideString;
end;
2: CellText := FColumns[Node.Parent.Parent.Index][Node.Parent.Index][Node.Index];
end;