diff --git a/src/AddIns/Misc/SharpServerTools/OracleDbToolsProvider/OracleDbToolsProvider.csproj b/src/AddIns/Misc/SharpServerTools/OracleDbToolsProvider/OracleDbToolsProvider.csproj
new file mode 100644
index 0000000000..b5fc6907b7
--- /dev/null
+++ b/src/AddIns/Misc/SharpServerTools/OracleDbToolsProvider/OracleDbToolsProvider.csproj
@@ -0,0 +1,68 @@
+
+
+ Library
+ OracleDbToolsProvider
+ OracleDbToolsProvider
+ Debug
+ AnyCPU
+ {DFA70EAA-3285-4BC0-BCA7-EBEC4D67FC9B}
+ False
+ False
+ False
+ Auto
+ 4194304
+ AnyCPU
+ 4096
+ 4
+ false
+
+
+ ..\..\..\..\..\AddIns\AddIns\Misc\SharpServerTools\
+ False
+ DEBUG;TRACE
+ true
+ Full
+ True
+
+
+ bin\Release\
+ True
+ TRACE
+ False
+ None
+ False
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {35CEF10F-2D4C-45F2-9DD1-161E0FEC583C}
+ ICSharpCode.Core
+
+
+ {2748AD25-9C63-4E12-877B-4DCE96FBED54}
+ ICSharpCode.SharpDevelop
+
+
+ {D721EAA4-8A40-4EF0-A011-5862159BE621}
+ ServerBrowserTool
+
+
+ {93B2D6DF-7588-40C0-8A35-CA0DD7328FC3}
+ SharpDbTools
+
+
+
+
\ No newline at end of file
diff --git a/src/AddIns/Misc/SharpServerTools/OracleDbToolsProvider/OracleDbToolsProvider.sln b/src/AddIns/Misc/SharpServerTools/OracleDbToolsProvider/OracleDbToolsProvider.sln
new file mode 100644
index 0000000000..6584b7f7f7
--- /dev/null
+++ b/src/AddIns/Misc/SharpServerTools/OracleDbToolsProvider/OracleDbToolsProvider.sln
@@ -0,0 +1,6 @@
+Microsoft Visual Studio Solution File, Format Version 9.00
+# SharpDevelop 2.1.0.1900
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OracleDbToolsProvider", "OracleDbToolsProvider.csproj", "{DFA70EAA-3285-4BC0-BCA7-EBEC4D67FC9B}"
+EndProject
+Global
+EndGlobal
diff --git a/src/AddIns/Misc/SharpServerTools/OracleDbToolsProvider/OracleSharpDbToolsProvider.csproj b/src/AddIns/Misc/SharpServerTools/OracleDbToolsProvider/OracleSharpDbToolsProvider.csproj
new file mode 100644
index 0000000000..142121f653
--- /dev/null
+++ b/src/AddIns/Misc/SharpServerTools/OracleDbToolsProvider/OracleSharpDbToolsProvider.csproj
@@ -0,0 +1,67 @@
+
+
+ Library
+ OracleDbToolsProvider
+ OracleSharpDbToolsProvider
+ Debug
+ AnyCPU
+ {2B4FE109-816C-4397-BFBE-077E1763A7A4}
+ False
+ False
+ False
+ Auto
+ 4194304
+ AnyCPU
+ 4096
+ 4
+ false
+
+
+ obj\
+ obj\Debug\
+ ..\..\..\..\..\..\AddIns\AddIns\Misc\SharpServerTools\
+ False
+ DEBUG;TRACE
+ true
+ Full
+ True
+
+
+ obj\
+ obj\Release\
+ bin\Release\
+ True
+ TRACE
+ False
+ None
+ False
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {35CEF10F-2D4C-45F2-9DD1-161E0FEC583C}
+ ICSharpCode.Core
+
+
+ {E8922383-B6F5-4107-AB82-49662D98B2FE}
+ SharpServerTools
+
+
+ {2748AD25-9C63-4E12-877B-4DCE96FBED54}
+ ICSharpCode.SharpDevelop
+
+
+
+
\ No newline at end of file
diff --git a/src/AddIns/Misc/SharpServerTools/OracleDbToolsProvider/Src/Forms/OracleFormsArtefactFactory.cs b/src/AddIns/Misc/SharpServerTools/OracleDbToolsProvider/Src/Forms/OracleFormsArtefactFactory.cs
new file mode 100644
index 0000000000..6836a93f88
--- /dev/null
+++ b/src/AddIns/Misc/SharpServerTools/OracleDbToolsProvider/Src/Forms/OracleFormsArtefactFactory.cs
@@ -0,0 +1,90 @@
+/*
+ * User: dickon
+ * Date: 17/09/2006
+ * Time: 09:10
+ *
+ */
+
+using System;
+using System.Windows.Forms;
+using System.Data;
+
+using SharpDbTools.Forms;
+using SharpDbTools.Data;
+
+using SharpServerTools.Forms;
+
+using ICSharpCode.Core;
+
+namespace SharpDbTools.Oracle.Forms
+{
+ ///
+ /// Description of MetaDataNodeBuilder.
+ /// TODO: currently this is just a flat list - need to reflect ownership
+ /// relationships such as schema etc
+ ///
+ public class OracleFormsArtefactFactory : FormsArtefactFactory
+ {
+ public OracleFormsArtefactFactory()
+ {
+ }
+
+ public override TreeNode CreateMetaDataNode(string logicalConnectionName)
+ {
+ LoggingService.Debug(this.GetType().ToString()
+ + ": creating MetaDataNode for: " + logicalConnectionName);
+ // create root node of the metadata collections tree
+
+ TreeNode metaNode = new TreeNode("Db Objects");
+ metaNode.Name = logicalConnectionName + ":MetaData";
+
+ // retrieve the metadata for this logical connection name
+
+ DbModelInfo info = DbModelInfoService.GetDbModelInfo(logicalConnectionName);
+
+ // retrieve the table listing the metadata collections
+
+ DataTable metadataCollectionsTable = info.Tables[TableNames.MetaDataCollections];
+
+ // if it exists then populate the tree
+
+ if (metadataCollectionsTable != null) {
+ LoggingService.Debug(this.GetType().ToString() + ": found metadata collections table, " +
+ " building node...");
+ for (int i = 0; i < TableNames.PrimaryObjects.Length; i++) {
+ string metadataCollectionName = TableNames.PrimaryObjects[i];
+ LoggingService.Debug("looking for metadata: " + metadataCollectionName);
+ DataTable metaCollectionTable = info.Tables[metadataCollectionName];
+ LoggingService.Debug("found metadata collection: " + metadataCollectionName);
+ TreeNode collectionNode = new TreeNode(metadataCollectionName);
+ collectionNode.Name = logicalConnectionName + ":Collection:" + metadataCollectionName;
+ metaNode.Nodes.Add(collectionNode);
+ foreach (DataRow dbObjectRow in metaCollectionTable.Rows) {
+ TreeNode objectNode = null;
+ if (dbObjectRow.ItemArray.Length > 1) {
+
+ // if it is a table metadata collection then create a node
+ // with the option to invoke the DescribeTableViewContent
+
+ if (metadataCollectionName.Equals("Tables")) {
+ objectNode = new TableTreeNode((string)dbObjectRow[1], logicalConnectionName);
+ } else {
+
+ // TODO: describe other metadata collections
+
+ objectNode = new TreeNode((string)dbObjectRow[1]);
+ }
+ objectNode.Name = logicalConnectionName + ":Object:" + (string)dbObjectRow[1];
+ } else {
+ objectNode = new TreeNode((string)dbObjectRow[0]);
+ objectNode.Name = logicalConnectionName + ":Object:" + (string)dbObjectRow[0];
+ }
+ collectionNode.Nodes.Add(objectNode);
+ }
+ }
+ }
+ return metaNode;
+ }
+ }
+
+}
diff --git a/src/AddIns/Misc/SharpServerTools/OracleDbToolsProvider/Src/Forms/TableTreeNode.cs b/src/AddIns/Misc/SharpServerTools/OracleDbToolsProvider/Src/Forms/TableTreeNode.cs
new file mode 100644
index 0000000000..20339c2844
--- /dev/null
+++ b/src/AddIns/Misc/SharpServerTools/OracleDbToolsProvider/Src/Forms/TableTreeNode.cs
@@ -0,0 +1,56 @@
+/*
+ * User: dickon
+ * Date: 23/09/2006
+ * Time: 10:57
+ *
+ */
+
+using System;
+using System.Drawing;
+using System.Windows.Forms;
+using System.Data;
+
+using SharpDbTools.Forms;
+using SharpDbTools.Data;
+
+using SharpServerTools.Forms;
+
+using ICSharpCode.Core;
+using ICSharpCode.SharpDevelop;
+using ICSharpCode.SharpDevelop.Gui;
+
+namespace SharpDbTools.Oracle.Forms
+{
+ ///
+ /// specialisation of the TreeNode to add context menu and click handling
+ /// to invoke the DescribeTable component for Oracle tables.
+ /// Does not change any data or metadata content so does not need to be
+ /// a ServerExplorerTreeNode
+ ///
+
+ class TableTreeNode: TreeNode
+ {
+ string logicalConnectionName;
+
+ public TableTreeNode(string objectName, string logicalConnectionName): base(objectName)
+ {
+ this.logicalConnectionName = logicalConnectionName;
+ NodeAwareContextMenuStrip cMenu = new NodeAwareContextMenuStrip(this);
+ ToolStripMenuItem invokeDescriberMenuItem = new ToolStripMenuItem("Describe");
+ invokeDescriberMenuItem.Click += new EventHandler(DescribeTableClickHandler);
+ cMenu.Items.Add(invokeDescriberMenuItem);
+ this.ContextMenuStrip = cMenu;
+ }
+
+ public void DescribeTableClickHandler(object sender, EventArgs args)
+ {
+ ToolStripMenuItem item = sender as ToolStripMenuItem;
+ NodeAwareContextMenuStrip s = item.Owner as NodeAwareContextMenuStrip;
+ string tableName = s.TreeNode.Text;
+ LoggingService.Debug("describe table clicked for: " + logicalConnectionName + " and table name: " + tableName);
+ DataTable tableInfo = DbModelInfoService.GetTableInfo(logicalConnectionName, tableName);
+ TableDescribeViewContent tableDescribeViewContent = new TableDescribeViewContent(tableInfo, tableName);
+ WorkbenchSingleton.Workbench.ShowView(tableDescribeViewContent);
+ }
+ }
+}
diff --git a/src/AddIns/Misc/SharpServerTools/ServerBrowserTool/ServerBrowserTool.csproj b/src/AddIns/Misc/SharpServerTools/ServerBrowserTool/ServerBrowserTool.csproj
new file mode 100644
index 0000000000..87b6e49764
--- /dev/null
+++ b/src/AddIns/Misc/SharpServerTools/ServerBrowserTool/ServerBrowserTool.csproj
@@ -0,0 +1,67 @@
+
+
+ Library
+ ServerBrowserTool
+ ServerBrowserTool
+ Debug
+ AnyCPU
+ {D721EAA4-8A40-4EF0-A011-5862159BE621}
+ False
+ False
+ False
+ Auto
+ 4194304
+ AnyCPU
+ 4096
+ 4
+ false
+
+
+ ..\..\..\..\..\AddIns\AddIns\Misc\SharpServerTools\
+ False
+ DEBUG;TRACE
+ true
+ Full
+ True
+
+
+ bin\Release\
+ True
+ TRACE
+ False
+ None
+ False
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Always
+
+
+ {35CEF10F-2D4C-45F2-9DD1-161E0FEC583C}
+ ICSharpCode.Core
+
+
+ {2748AD25-9C63-4E12-877B-4DCE96FBED54}
+ ICSharpCode.SharpDevelop
+
+
+
+
\ No newline at end of file
diff --git a/src/AddIns/Misc/SharpServerTools/ServerBrowserTool/ServerBrowserTool.sln b/src/AddIns/Misc/SharpServerTools/ServerBrowserTool/ServerBrowserTool.sln
new file mode 100644
index 0000000000..3c3a31667c
--- /dev/null
+++ b/src/AddIns/Misc/SharpServerTools/ServerBrowserTool/ServerBrowserTool.sln
@@ -0,0 +1,6 @@
+Microsoft Visual Studio Solution File, Format Version 9.00
+# SharpDevelop 2.1.0.1900
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServerBrowserTool", "ServerBrowserTool.csproj", "{D721EAA4-8A40-4EF0-A011-5862159BE621}"
+EndProject
+Global
+EndGlobal
diff --git a/src/AddIns/Misc/SharpServerTools/ServerBrowserTool/SharpServerTools.addin b/src/AddIns/Misc/SharpServerTools/ServerBrowserTool/SharpServerTools.addin
new file mode 100644
index 0000000000..887d848e38
--- /dev/null
+++ b/src/AddIns/Misc/SharpServerTools/ServerBrowserTool/SharpServerTools.addin
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/AddIns/Misc/SharpServerTools/ServerBrowserTool/Src/Configuration/AssemblyInfo.cs b/src/AddIns/Misc/SharpServerTools/ServerBrowserTool/Src/Configuration/AssemblyInfo.cs
new file mode 100644
index 0000000000..888d27d92e
--- /dev/null
+++ b/src/AddIns/Misc/SharpServerTools/ServerBrowserTool/Src/Configuration/AssemblyInfo.cs
@@ -0,0 +1,31 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// Information about this assembly is defined by the following
+// attributes.
+//
+// change them to the information which is associated with the assembly
+// you compile.
+
+[assembly: AssemblyTitle("ServerBrowserTool")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("ServerBrowserTool")]
+[assembly: AssemblyCopyright("")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// This sets the default COM visibility of types in the assembly to invisible.
+// If you need to expose a type to COM, use [ComVisible(true)] on that type.
+[assembly: ComVisible(false)]
+
+// The assembly version has following format :
+//
+// Major.Minor.Build.Revision
+//
+// You can specify all values by your own or you can build default build and revision
+// numbers with the '*' character (the default):
+
+[assembly: AssemblyVersion("1.0.*")]
diff --git a/src/AddIns/Misc/SharpServerTools/ServerBrowserTool/Src/Forms/IInitializable.cs b/src/AddIns/Misc/SharpServerTools/ServerBrowserTool/Src/Forms/IInitializable.cs
new file mode 100644
index 0000000000..f943a31f6d
--- /dev/null
+++ b/src/AddIns/Misc/SharpServerTools/ServerBrowserTool/Src/Forms/IInitializable.cs
@@ -0,0 +1,19 @@
+/*
+ * User: dickon
+ * Date: 01/10/2006
+ * Time: 23:22
+ *
+ */
+
+using System;
+
+namespace SharpServerTools.Forms
+{
+ ///
+ /// Implemented by anything that is initializable
+ ///
+ public interface IInitializable
+ {
+ void Initialize();
+ }
+}
diff --git a/src/AddIns/Misc/SharpServerTools/ServerBrowserTool/Src/Forms/NodeAwareContextMenuStrip.cs b/src/AddIns/Misc/SharpServerTools/ServerBrowserTool/Src/Forms/NodeAwareContextMenuStrip.cs
new file mode 100644
index 0000000000..52a16be786
--- /dev/null
+++ b/src/AddIns/Misc/SharpServerTools/ServerBrowserTool/Src/Forms/NodeAwareContextMenuStrip.cs
@@ -0,0 +1,28 @@
+/*
+ * User: dickon
+ * Date: 23/09/2006
+ * Time: 23:09
+ *
+ */
+
+using System;
+using System.Windows.Forms;
+
+namespace SharpServerTools.Forms
+{
+ public class NodeAwareContextMenuStrip : ContextMenuStrip
+ {
+ TreeNode treeNodeAttached;
+
+ public NodeAwareContextMenuStrip(TreeNode treeNodeAttached) : base()
+ {
+ this.treeNodeAttached = treeNodeAttached;
+ }
+
+ public TreeNode TreeNode {
+ get {
+ return treeNodeAttached;
+ }
+ }
+ }
+}
diff --git a/src/AddIns/Misc/SharpServerTools/ServerBrowserTool/Src/Forms/RebuildRequiredEvents.cs b/src/AddIns/Misc/SharpServerTools/ServerBrowserTool/Src/Forms/RebuildRequiredEvents.cs
new file mode 100644
index 0000000000..4cd5702b38
--- /dev/null
+++ b/src/AddIns/Misc/SharpServerTools/ServerBrowserTool/Src/Forms/RebuildRequiredEvents.cs
@@ -0,0 +1,56 @@
+/*
+ * User: dickon
+ * Date: 24/09/2006
+ * Time: 08:01
+ *
+ */
+
+using System;
+using System.Windows.Forms;
+using System.Collections;
+
+namespace SharpServerTools.Forms
+{
+
+ ///
+ /// An IRebuildable can be asked to rebuild its Node tree
+ ///
+ public interface IRebuildable
+ {
+ void Rebuild();
+ }
+
+ ///
+ /// An IRequiresRebuildSource can request the ServerToolTreeView to rebuild
+ /// it by emitting the RebuildRequiredEvent
+ ///
+ public interface IRequiresRebuildSource
+ {
+ event RebuildRequiredEventHandler RebuildRequiredEvent;
+ }
+
+ public delegate void RebuildRequiredEventHandler(object sender, RebuildRequiredEventArgs e);
+
+ ///
+ /// An IRequiresRebuildSource should add a reference to itself to
+ /// this event if it wants to be rebuilt.
+ /// The parent of an IRequiresRebuildSource may or may not add itself
+ /// and resend the event to the ServerToolTreeView depending on the
+ /// relationship between parent and child.
+ ///
+ public class RebuildRequiredEventArgs: EventArgs
+ {
+ ArrayList rebuildNodes = new ArrayList();
+
+ public IEnumerable Nodes {
+ get {
+ return rebuildNodes;
+ }
+ }
+
+ public void AddNode(IRebuildable node)
+ {
+ rebuildNodes.Add(node);
+ }
+ }
+}
diff --git a/src/AddIns/Misc/SharpServerTools/ServerBrowserTool/Src/Forms/ServerBrowserTool.cs b/src/AddIns/Misc/SharpServerTools/ServerBrowserTool/Src/Forms/ServerBrowserTool.cs
new file mode 100644
index 0000000000..781491f573
--- /dev/null
+++ b/src/AddIns/Misc/SharpServerTools/ServerBrowserTool/Src/Forms/ServerBrowserTool.cs
@@ -0,0 +1,78 @@
+//
+//
+//
+//
+// $Revision: 1766 $
+//
+
+/*
+ * User: Dickon Field
+ * Date: 12/06/2006
+ * Time: 06:25
+ */
+
+using System;
+using System.Windows.Forms;
+using System.Collections.Generic;
+
+using ICSharpCode.Core;
+using ICSharpCode.SharpDevelop.Gui;
+
+
+namespace SharpServerTools.Forms
+{
+ ///
+ /// Enables a user to browse metadata associated with a db server and to open resources
+ /// referenced therein. The intention is to extend this to other server processes over
+ /// time.
+ ///
+ public class ServerBrowserTool : AbstractPadContent
+ {
+ Panel ctl;
+ ServerToolTreeView dbTree;
+
+ ///
+ /// ServerBrowserTool hosts one or more TreeViews providing views of types
+ /// of server. Currently it shows only relational database servers.
+ ///
+ public ServerBrowserTool()
+ {
+ LoggingService.Debug("Loading ServerBrowserTool");
+ dbTree = new ServerToolTreeView();
+ dbTree.Dock = DockStyle.Fill;
+ ctl = new Panel();
+ ctl.Controls.Add(dbTree);
+ dbTree.Rebuild();
+ }
+
+ ///
+ /// The representing the pad
+ ///
+ public override Control Control {
+ get {
+ return ctl;
+ }
+ }
+
+ ///
+ /// Rebuildes the pad
+ ///
+ public override void RedrawContent()
+ {
+
+ }
+
+ ///
+ /// Cleans up all used resources
+ ///
+ public override void Dispose()
+ {
+ ctl.Dispose();
+ }
+ }
+}
+
+
+
+
+
diff --git a/src/AddIns/Misc/SharpServerTools/ServerBrowserTool/Src/Forms/ServerToolTreeView.cs b/src/AddIns/Misc/SharpServerTools/ServerBrowserTool/Src/Forms/ServerToolTreeView.cs
new file mode 100644
index 0000000000..18dc82bb3f
--- /dev/null
+++ b/src/AddIns/Misc/SharpServerTools/ServerBrowserTool/Src/Forms/ServerToolTreeView.cs
@@ -0,0 +1,77 @@
+/*
+ * User: dickon
+ * Date: 23/09/2006
+ * Time: 23:07
+ *
+ */
+
+using System;
+using System.Windows.Forms;
+using System.Collections;
+
+using ICSharpCode.Core;
+using ICSharpCode.SharpDevelop.Gui;
+
+namespace SharpServerTools.Forms
+{
+ ///
+ /// Provides a tree-structured visual rendering of server instances.
+ /// This class should not hold references to server data, but should render its
+ /// content using data retrieved from business services responsible for
+ /// maintaining this model/s of underlying services.
+ ///
+ public class ServerToolTreeView : TreeView, IRebuildable
+ {
+ public ServerToolTreeView(): base()
+ {
+ // TODO: iterate through plugins retrieved from AddIn Tree
+ Type dbExplorerType = Type.GetType("SharpDbTools.Forms.DatabaseExplorerTreeNode, SharpDbTools");
+ TreeNode dbExplorerNode = (TreeNode)Activator.CreateInstance(dbExplorerType);
+ IRequiresRebuildSource s = dbExplorerNode as IRequiresRebuildSource;
+ s.RebuildRequiredEvent += new RebuildRequiredEventHandler(RebuildRequiredNotify);
+ this.Nodes.Add(dbExplorerNode);
+ }
+
+ public void RebuildChildren(IEnumerable children)
+ {
+ // Rebuild each of the root nodes in the ServerToolTreeView
+ // Currently this comprises the Database Explorer
+ IEnumerable n = children;
+ if (n == null) {
+ n = this.Nodes;
+ }
+
+ this.BeginUpdate();
+ foreach (object o in n) {
+ IRebuildable se = (IRebuildable)o;
+ se.Rebuild();
+ }
+ this.EndUpdate();
+ }
+
+ private void RebuildRequiredNotify(object sender, RebuildRequiredEventArgs e)
+ {
+ IEnumerable children = e.Nodes;
+ if (this.InvokeRequired) {
+ this.Invoke(new RebuildChildrenDelegate(RebuildChildren), new object[] {children});
+ }
+ else {
+ RebuildChildren(children);
+ }
+
+ }
+
+ public void Rebuild()
+ {
+ if (this.InvokeRequired) {
+ this.Invoke(new RebuildChildrenDelegate(RebuildChildren), new object[] {null});
+ }
+ else {
+ this.RebuildChildren(null);
+ }
+ }
+
+
+ }
+ public delegate void RebuildChildrenDelegate(IEnumerable children);
+}
diff --git a/src/AddIns/Misc/SharpServerTools/SharpDbTools/SharpDbTools.csproj b/src/AddIns/Misc/SharpServerTools/SharpDbTools/SharpDbTools.csproj
new file mode 100644
index 0000000000..077208b45e
--- /dev/null
+++ b/src/AddIns/Misc/SharpServerTools/SharpDbTools/SharpDbTools.csproj
@@ -0,0 +1,76 @@
+
+
+ Library
+ SharpDbTools
+ SharpDbTools
+ Debug
+ AnyCPU
+ {93B2D6DF-7588-40C0-8A35-CA0DD7328FC3}
+
+
+ bin\Debug\
+ False
+ DEBUG;TRACE
+ True
+ Full
+ True
+
+
+ bin\Release\
+ True
+ TRACE
+ False
+ None
+ False
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ConnectionStringDefinitionDialog.cs
+
+
+ GetConnectionLogicalNameDialog.cs
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {35CEF10F-2D4C-45F2-9DD1-161E0FEC583C}
+ ICSharpCode.Core
+
+
+ {2748AD25-9C63-4E12-877B-4DCE96FBED54}
+ ICSharpCode.SharpDevelop
+
+
+ {D721EAA4-8A40-4EF0-A011-5862159BE621}
+ ServerBrowserTool
+
+
+
+
\ No newline at end of file
diff --git a/src/AddIns/Misc/SharpServerTools/SharpDbTools/SharpDbTools.sln b/src/AddIns/Misc/SharpServerTools/SharpDbTools/SharpDbTools.sln
new file mode 100644
index 0000000000..d3ccf3f2f3
--- /dev/null
+++ b/src/AddIns/Misc/SharpServerTools/SharpDbTools/SharpDbTools.sln
@@ -0,0 +1,6 @@
+Microsoft Visual Studio Solution File, Format Version 9.00
+# SharpDevelop 2.1.0.1900
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpDbTools", "SharpDbTools.csproj", "{93B2D6DF-7588-40C0-8A35-CA0DD7328FC3}"
+EndProject
+Global
+EndGlobal
diff --git a/src/AddIns/Misc/SharpServerTools/SharpDbTools/Src/Configuration/AssemblyInfo.cs b/src/AddIns/Misc/SharpServerTools/SharpDbTools/Src/Configuration/AssemblyInfo.cs
new file mode 100644
index 0000000000..bb222f9790
--- /dev/null
+++ b/src/AddIns/Misc/SharpServerTools/SharpDbTools/Src/Configuration/AssemblyInfo.cs
@@ -0,0 +1,21 @@
+//
+//
+//
+//
+// $Revision: 1760 $
+//
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+// Information about this assembly is defined by the following
+// attributes.
+//
+// change them to the information which is associated with the assembly
+// you compile.
+
+[assembly: AssemblyTitle("SharpDbTools")]
+[assembly: AssemblyDescription("Addin for SharpDevelop 2.0")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
diff --git a/src/AddIns/Misc/SharpServerTools/SharpDbTools/Src/Data/ColumnNames.cs b/src/AddIns/Misc/SharpServerTools/SharpDbTools/Src/Data/ColumnNames.cs
new file mode 100644
index 0000000000..00a6ba5754
--- /dev/null
+++ b/src/AddIns/Misc/SharpServerTools/SharpDbTools/Src/Data/ColumnNames.cs
@@ -0,0 +1,34 @@
+//
+//
+//
+//
+// $Revision: 1784 $
+//
+
+/*
+ * User: dickon
+ * Date: 30/07/2006
+ * Time: 23:37
+ *
+ */
+
+using System;
+
+namespace SharpDbTools.Data
+{
+ ///
+ /// Description of Columns.
+ ///
+ public sealed class ColumnNames
+ {
+ public const string InvariantName = "invariantName";
+ public const string Name = "name";
+ public const string ConnectionString = "connectionString";
+ public const string TableName = "TABLE_NAME";
+ public static string[] TableTableFieldsToDisplay =
+ new string [] {"COLUMN_NAME", "DATATYPE",
+ "LENGTH", "PRECISION", "SCALE", "NULLABLE"};
+ public static string[] TableTableFieldsColumnHeaders =
+ new string[] { "Column", "Type", "Length", "Precision", "Scale", "Nullable" };
+ }
+}
diff --git a/src/AddIns/Misc/SharpServerTools/SharpDbTools/Src/Data/DbModelInfo.cs b/src/AddIns/Misc/SharpServerTools/SharpDbTools/Src/Data/DbModelInfo.cs
new file mode 100644
index 0000000000..f1ecb9cc15
--- /dev/null
+++ b/src/AddIns/Misc/SharpServerTools/SharpDbTools/Src/Data/DbModelInfo.cs
@@ -0,0 +1,181 @@
+//
+//
+//
+//
+// $Revision: 1784 $
+//
+
+/*
+ * User: Dickon Field
+ * Date: 10/07/2006
+ * Time: 09:12
+ *
+ */
+
+using System;
+using System.Data;
+using System.Data.Common;
+using System.Collections.Generic;
+
+using ICSharpCode.Core;
+
+namespace SharpDbTools.Data
+{
+ ///
+ /// DbModel is a DataSet containing the metadata tables returned from a DbConnection.
+ /// It adds methods designed specifically to facilitate access to the data in the
+ /// DataTables contained by the DbModel.
+ ///
+ /// The DbModel class is intended to be usable in a fully disconnected mode - that is,
+ /// it requires a DbConnection to populate it, but it may then be locally persisted and subsequently
+ /// retrieved from its persisted data. This is intended to allow work to progress against the
+ /// DbModel without requiring a connection to its RDB server.
+ ///
+ ///
+ public class DbModelInfo: DataSet
+ {
+ public const string METADATACOLLECTIONS = "MetaDataCollections";
+
+ public DbModelInfo() : base()
+ {
+ }
+
+ public DbModelInfo(string name) : base()
+ {
+ DataTable table = CreateConnectionInfoTable();
+ // add the first and only column of this table;
+ table.Rows.Add(new object[] {name, null, null});
+ }
+
+ public DbModelInfo(string name, string invariantName, string connectionString): base()
+ {
+ DataTable table = CreateConnectionInfoTable();
+ // add the first and only column of this table;
+ table.Rows.Add(new object[] {name, invariantName, connectionString});
+ }
+
+ public string Name {
+ get {
+ DataTable table = this.Tables[TableNames.ConnectionInfo];
+ string name = table.Rows[0][ColumnNames.Name] as string;
+ return name;
+ }
+ }
+
+ public string InvariantName {
+ get {
+ DataTable table = this.Tables[TableNames.ConnectionInfo];
+ string invariantName = null;
+ try {
+ invariantName = table.Rows[0][ColumnNames.InvariantName] as string;
+ }
+ catch(ArgumentException) {
+ // see comment below - it is correct to bury this exception
+ //LoggingService.Info("InvariantName property was accessed while undefined" + e);
+ }
+ return invariantName;
+ }
+ set {
+ DataTable table = this.Tables[TableNames.ConnectionInfo];
+ string invariantName = table.Rows[0][ColumnNames.InvariantName] as string;
+ string name = this.Name;
+ string connectionString = this.ConnectionString;
+
+ if (invariantName == null) {
+ table.Rows[0][ColumnNames.InvariantName] = value;
+ }
+
+ // if invariant has changed must clear any existing metadata
+ else if (!(invariantName.Equals(value))) {
+ // clear tables
+ this.Clear();
+ DataTable newTable = CreateConnectionInfoTable();
+ // add the first and only column of this table;
+ newTable.Rows.Add(new object[] {name, invariantName, connectionString});
+ }
+ }
+ }
+
+ public string ConnectionString {
+ get {
+ DataTable table = this.Tables[TableNames.ConnectionInfo];
+ string connectionString = null;
+ try {
+ connectionString = table.Rows[0][ColumnNames.ConnectionString] as string;
+ }
+ catch(ArgumentException) {
+ // this simply indicates that this attribute was not defined when the
+ // DbModelInfo was saved, returning null makes sense here - so it is
+ // correct to bury this exception
+ //LoggingService.Info("InvariantName property was accessed while undefined" + e);
+ }
+ return connectionString;
+ }
+ set {
+ DataTable table = this.Tables[TableNames.ConnectionInfo];
+ string connectionString = this.ConnectionString;
+ if (connectionString == null) {
+ table.Rows[0][ColumnNames.ConnectionString] = value;
+ }
+ else if (!(connectionString.Equals(value))) {
+ string invariantName = this.InvariantName;
+ string name = this.Name;
+ this.Clear();
+ // add the first and only column of this table;
+ table.Rows.Add(new object[] {name, invariantName, value});
+ }
+ }
+ }
+
+ public void SetConnectionInfo(string invariantName, string connectionString)
+ {
+ string name = this.Name;
+ SetConnectionInfo(name, invariantName, connectionString);
+ }
+
+ public void SetConnectionInfo(string name, string invariantName,
+ string connectionString)
+ {
+ this.Clear();
+ DataTable table = CreateConnectionInfoTable();
+ // add the first and only column of this table;
+ table.Rows.Add(new object[] {name, invariantName, connectionString});
+
+ }
+
+ private DataTable CreateConnectionInfoTable()
+ {
+ // create a table in the DbModelInfo to hold this initial info.
+ // this creates a consistent representation of the data and makes
+ // it easier to serialise it
+ DataTable table = this.Tables.Add(TableNames.ConnectionInfo);
+ table.Columns.Add(ColumnNames.Name, typeof(string));
+ table.Columns.Add(ColumnNames.InvariantName, typeof(string));
+ table.Columns.Add(ColumnNames.ConnectionString, typeof(string));
+ return table;
+ }
+
+ public void ClearMetaData()
+ {
+ DataTable metadataCollectionsTable = this.MetaDataCollections;
+ if (metadataCollectionsTable != null) {
+ foreach (DataRow collectionRow in metadataCollectionsTable.Rows) {
+ String collectionName = (string)collectionRow[0];
+ this.Tables.Remove(collectionName);
+ }
+ }
+ }
+
+ public DataTable MetaDataCollections {
+ get {
+ return this.Tables[METADATACOLLECTIONS];
+ }
+ }
+
+ public DataTable this[string collectionName] {
+ get {
+ return this.Tables[collectionName];
+ }
+ }
+ }
+}
diff --git a/src/AddIns/Misc/SharpServerTools/SharpDbTools/Src/Data/DbModelInfoService.cs b/src/AddIns/Misc/SharpServerTools/SharpDbTools/Src/Data/DbModelInfoService.cs
new file mode 100644
index 0000000000..76475d1d82
--- /dev/null
+++ b/src/AddIns/Misc/SharpServerTools/SharpDbTools/Src/Data/DbModelInfoService.cs
@@ -0,0 +1,295 @@
+//
+//
+//
+//
+// $Revision: 1784 $
+//
+
+/*
+ * User: dickon
+ * Date: 28/07/2006
+ * Time: 21:55
+ *
+ */
+
+using System;
+using System.Data;
+using System.Data.Common;
+using System.Collections.Generic;
+using System.IO;
+using ICSharpCode.Core;
+
+namespace SharpDbTools.Data
+{
+ ///
+ /// Manages a collection of DbModelInfo:
+ /// - retrieval from files
+ /// - opening (essentially refreshing) from a database connection
+ /// - adding for new connection data (name, invariant name, connection string)
+ /// - saving to files
+ ///
+ public static class DbModelInfoService
+ {
+ static string saveLocation = null;
+ static object lockObject = new Object();
+ const string dbFilesDir = "DbTools";
+ static SortedList cache = null;
+
+ public static IList Names {
+ get {
+ lock(lockObject) {
+ if (cache == null) {
+ cache = new SortedList();
+ LoadNamesFromFiles();
+ }
+ }
+ return cache.Keys;
+ }
+ }
+
+ ///
+ ///
+ ///
+ /// The user readable name of the provider
+ /// the identifying name of the provider
+ /// the connection string for this connection
+ ///
+ public static DbModelInfo Add(string name, string invariantName, string connectionString)
+ {
+ // TODO: add validation on name; invariant name
+ // assume that connection string is valid - if it fails an exception will be thrown later
+ // this allows partially defined connection strings at least to be saved and worked on later
+ DbModelInfo dbModel = new DbModelInfo(name, invariantName, connectionString);
+
+ // add to cache
+ cache.Add(name, dbModel);
+ return dbModel;
+ }
+
+ public static void Remove(string name)
+ {
+ cache.Remove(name);
+ }
+
+ public static DbModelInfo GetDbModelInfo(string name) {
+ DbModelInfo modelInfo = null;
+ bool exists = cache.TryGetValue(name, out modelInfo);
+ return modelInfo;
+ }
+
+ public static DataTable GetTableInfo(string modelName, string tableName)
+ {
+ LoggingService.Debug("-->GetTableInfo");
+ DbModelInfo modelInfo = GetDbModelInfo(modelName);
+ DataTable columnTable = modelInfo.Tables[TableNames.Columns];
+ DataRow[] columnsMetadata = columnTable.Select(ColumnNames.TableName + "='" + tableName + "'");
+ LoggingService.Debug("found: " + columnsMetadata.Length + " columns belonging to table: " + tableName);
+ DataTable tableInfo = new DataTable();
+ DataColumnCollection cols = columnTable.Columns;
+ foreach (DataColumn c in cols) {
+ DataColumn nc = new DataColumn(c.ColumnName, c.DataType);
+ tableInfo.Columns.Add(nc);
+ }
+ foreach (DataRow r in columnsMetadata) {
+ DataRow newRow = tableInfo.NewRow();
+ newRow.ItemArray = r.ItemArray;
+ tableInfo.Rows.Add(newRow);
+ tableInfo.AcceptChanges();
+ }
+ return tableInfo;
+
+ }
+
+ public static DbModelInfo LoadMetadataFromConnection(string name)
+ {
+ // get the DbModelInfo
+
+ DbModelInfo modelInfo = null;
+ bool exists = cache.TryGetValue(name, out modelInfo);
+ if (!exists)
+ {
+ // TODO: more detail...
+ throw new KeyNotFoundException();
+ }
+
+ // get the invariant name and connection string
+
+ string invariantName = modelInfo.InvariantName;
+ string connectionString = modelInfo.ConnectionString;
+
+ // get a connection - wait until a connection has been successfully made
+ // before clearing the DbModelInfo
+
+ DbProvidersService factoryService = DbProvidersService.GetDbProvidersService();
+ DbConnection connection = null;
+ try {
+
+ DbProviderFactory factory = factoryService.GetFactoryByInvariantName(invariantName);
+ connection = factory.CreateConnection();
+
+
+ modelInfo.ClearMetaData();
+
+ // reload the metadata from the connection
+ // get the Schema table
+ connection.ConnectionString = connectionString;
+
+ connection.Open();
+ DataTable schemaInfo = connection.GetSchema();
+
+ // clear the DbModelInfo prior to refreshing from the connection
+ modelInfo.ClearMetaData();
+
+ // iterate through the rows in it - the first column of each is a
+ // schema info collection name that can be retrieved as a DbTable
+ // Add each one to the DbModel DataSet
+
+ foreach (DataRow collectionRow in schemaInfo.Rows) {
+ String collectionName = (string)collectionRow[0];
+ DataTable nextMetaData = connection.GetSchema(collectionName);
+ modelInfo.Merge(nextMetaData);
+ }
+ return modelInfo;
+ }
+ catch(Exception e) {
+ LoggingService.Fatal("Exception caught while trying to retrieve database metadata: " + e);
+ throw e;
+ }
+ finally {
+ connection.Close();
+ }
+ }
+
+ ///
+ ///
+ ///
+ /// the logical name of the DbModelInfo to save to a file
+ /// if true, any existing file will be overwritten
+ /// true if the DbModelInfo was saved, false if not. It will not be saved if
+ /// either overwriteExistingFile is set to true, and there is an existing file
+ public static bool SaveToFile(string name, bool overwriteExistingFile)
+ {
+ string path = GetSaveLocation();
+ DbModelInfo modelInfo = null;
+ cache.TryGetValue(name, out modelInfo);
+ if (modelInfo != null) {
+ string modelName = modelInfo.Name;
+ // write to a file in 'path' called .metadata
+ // TODO: may want to consider ways of making this more resilient
+
+ string connectionProps = modelInfo.ConnectionString;
+ string invariantName = modelInfo.InvariantName;
+
+
+
+ string filePath = path + @"\" + name + ".metadata";
+ LoggingService.Debug("writing metadata to: " + filePath);
+ if (File.Exists(filePath)) {
+ if (overwriteExistingFile) {
+ File.Delete(filePath);
+ } else {
+ return false;
+ }
+ }
+ using (StreamWriter sw = File.CreateText(filePath)) {
+ string xml = modelInfo.GetXml();
+ sw.Write(xml);
+ sw.Flush();
+ sw.Close();
+ return true;
+ }
+ } else {
+ throw new DbModelInfoDoesNotExistException(name);
+ }
+ }
+
+ public static void SaveAll()
+ {
+ foreach (string name in cache.Keys) {
+ SaveToFile(name, true);
+ }
+ }
+
+ public static void LoadNamesFromFiles()
+ {
+ // load DbModelInfo's from file system
+ string saveLocation = GetSaveLocation();
+ LoggingService.Debug("looking for metadata files at: " + saveLocation);
+ string[] files = Directory.GetFileSystemEntries(saveLocation);
+
+ cache.Clear();
+ for (int i = 0; i < files.Length; i++) {
+ LoggingService.Debug("found to load metadata from: " + files[i]);
+ int start = files[i].LastIndexOf('\\');
+ int end = files[i].LastIndexOf('.');
+ start++;
+ string name = files[i].Substring(start, end - start);
+ DbModelInfo nextModel = new DbModelInfo(name);
+ cache.Add(nextModel.Name, nextModel);
+ }
+ }
+
+ public static void LoadFromFiles()
+ {
+ // load DbModelInfo's from file system
+ string saveLocation = GetSaveLocation();
+ string[] files = Directory.GetFiles(saveLocation);
+ cache.Clear();
+ for (int i = 0; i < files.Length; i++) {
+ DbModelInfo nextModel = LoadFromFileAtPath(@files[i]);
+ cache.Add(nextModel.Name, nextModel);
+ }
+ }
+
+ private static DbModelInfo LoadFromFileAtPath(string filePath)
+ {
+ LoggingService.Debug("loading DbModelInfo from filePath: " + filePath);
+ DbModelInfo nextModel = new DbModelInfo();
+ nextModel.ReadXml(filePath);
+ return nextModel;
+ }
+
+ public static void LoadFromFile(string logicalConnectionName)
+ {
+ LoggingService.Debug("loading DbModelInfo for name: " + logicalConnectionName);
+ string saveLocation = GetSaveLocation();
+ string path = saveLocation + "\\" + logicalConnectionName + ".metadata";
+ DbModelInfo info = LoadFromFileAtPath(path);
+ cache.Remove(logicalConnectionName);
+ cache.Add(logicalConnectionName, info);
+ }
+
+ private static string GetSaveLocation()
+ {
+ // append the path of the directory for saving Db files
+
+ if (saveLocation == null) {
+ lock(lockObject) {
+ string configDir = PropertyService.ConfigDirectory;
+ saveLocation = configDir + @"\" + dbFilesDir;
+ saveLocation = saveLocation.Replace("/", @"\");
+ }
+ }
+ if (!Directory.Exists(saveLocation)) {
+ Directory.CreateDirectory(@saveLocation);
+ }
+ return saveLocation;
+ }
+ }
+
+ public class DbModelInfoDoesNotExistException: ApplicationException
+ {
+ string name;
+
+ public DbModelInfoDoesNotExistException(string dbModelInfoName): base()
+ {
+ this.name = dbModelInfoName;
+ }
+
+ public string Name {
+ get {
+ return name;
+ }
+ }
+ }
+}
diff --git a/src/AddIns/Misc/SharpServerTools/SharpDbTools/Src/Data/DbProvidersService.cs b/src/AddIns/Misc/SharpServerTools/SharpDbTools/Src/Data/DbProvidersService.cs
new file mode 100644
index 0000000000..43e674ae3a
--- /dev/null
+++ b/src/AddIns/Misc/SharpServerTools/SharpDbTools/Src/Data/DbProvidersService.cs
@@ -0,0 +1,124 @@
+//
+//
+//
+//
+// $Revision: 1697 $
+//
+
+/*
+ * Responsibilities:
+ *
+ * Collaboration:
+ *
+ * User: Dickon Field
+ * Date: 21/05/2006
+ * Time: 23:19
+ *
+ */
+
+using System;
+using System.Data.Common;
+using System.Data;
+using System.Collections.Generic;
+
+using ICSharpCode.Core;
+
+namespace SharpDbTools.Data
+{
+ ///
+ /// A utility class that caches the DbProviderFactory and DbConnectionString
+ /// objects whose state is stored in the current processes config space.
+ ///
+ public class DbProvidersService
+ {
+ private static DbProvidersService me = new DbProvidersService();
+ private static Boolean initialized = false;
+ private Dictionary factories = new Dictionary();
+ private Dictionary factoriesByInvariantName = new Dictionary();
+
+ // This is only valid witin one session - do not persist
+ private Dictionary invariantByNameLookup = new Dictionary();
+ private List names = new List();
+
+ private DbProvidersService()
+ {
+ }
+
+ private void Initialize()
+ {
+ // get a complete list of config data for DbProviderFactories, indexed by name
+ DataTable providerFactoriesTable = DbProviderFactories.GetFactoryClasses();
+ DataRow[] rows = providerFactoriesTable.Select();
+
+ foreach(DataRow row in rows)
+ {
+ // TODO: factor out string literals for column names
+ string name = (string)row["Name"];
+ string invariantName = (string)row["InvariantName"];
+ LoggingService.Debug("adding lookup for: " + name + " to: + " + invariantName);
+ invariantByNameLookup.Add(name, invariantName);
+ //factoryData.Add(name, row);
+ LoggingService.Debug("retrieving DbProviderFactory for Name: " + name + " InvariantName: " + invariantName);
+ DbProviderFactory factory = DbProviderFactories.GetFactory(row);
+ names.Add(name);
+ factories.Add(name, factory);
+ factoriesByInvariantName.Add(invariantName, factory);
+ }
+
+ initialized = true;
+ }
+
+ public List Names
+ {
+ get
+ {
+ return names;
+ }
+ }
+
+ public string this[int i]
+ {
+ get
+ {
+ return names[i];
+ }
+ }
+
+ public string GetInvariantName(string name) {
+ string invariantName = null;
+ invariantByNameLookup.TryGetValue(name, out invariantName);
+ return invariantName;
+ }
+
+ public DbProviderFactory this[string name]
+ {
+ get
+ {
+ return factories[name];
+ }
+ set
+ {
+ factories[name] = value;
+ }
+ }
+
+ public DbProviderFactory GetFactoryByInvariantName(string invariantName)
+ {
+ DbProviderFactory factory = null;
+ this.factoriesByInvariantName.TryGetValue(invariantName, out factory);
+ return factory;
+ }
+
+ public static DbProvidersService GetDbProvidersService()
+ {
+ lock(me)
+ {
+ if (!initialized)
+ {
+ me.Initialize();
+ }
+ }
+ return me;
+ }
+ }
+}
diff --git a/src/AddIns/Misc/SharpServerTools/SharpDbTools/Src/Data/TableNames.cs b/src/AddIns/Misc/SharpServerTools/SharpDbTools/Src/Data/TableNames.cs
new file mode 100644
index 0000000000..d3c75e8675
--- /dev/null
+++ b/src/AddIns/Misc/SharpServerTools/SharpDbTools/Src/Data/TableNames.cs
@@ -0,0 +1,29 @@
+//
+//
+//
+//
+// $Revision: 1784 $
+//
+
+/*
+ * User: dickon
+ * Date: 30/07/2006
+ * Time: 23:35
+ *
+ */
+
+using System;
+
+namespace SharpDbTools.Data
+{
+ ///
+ /// Description of Tables.
+ ///
+ public sealed class TableNames
+ {
+ public const string MetaDataCollections = "MetaDataCollections";
+ public const string ConnectionInfo = "ConnectionInfo";
+ public static string[] PrimaryObjects = new string[] { "Tables", "Procedures", "Functions", "Views", "Users" };
+ public const string Columns = "Columns";
+ }
+}
diff --git a/src/AddIns/Misc/SharpServerTools/SharpDbTools/Src/Forms/ConnectionStringDefinitionDialog.Designer.cs b/src/AddIns/Misc/SharpServerTools/SharpDbTools/Src/Forms/ConnectionStringDefinitionDialog.Designer.cs
new file mode 100644
index 0000000000..757a491845
--- /dev/null
+++ b/src/AddIns/Misc/SharpServerTools/SharpDbTools/Src/Forms/ConnectionStringDefinitionDialog.Designer.cs
@@ -0,0 +1,239 @@
+/*
+ * Responsibilities:
+ *
+ * Collaboration:
+ *
+ * User: ${USER}
+ * Date: ${DATE}
+ * Time: ${TIME}
+ *
+ */
+namespace SharpDbTools.Forms
+{
+ partial class ConnectionStringDefinitionDialog : System.Windows.Forms.Form
+ {
+ ///
+ /// Designer variable used to keep track of non-visual components.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Disposes resources used by the form.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing) {
+ if (components != null) {
+ components.Dispose();
+ }
+ }
+ base.Dispose(disposing);
+ }
+
+ ///
+ /// This method is required for Windows Forms designer support.
+ /// Do not change the method contents inside the source code editor. The Forms designer might
+ /// not be able to load this method if it was changed manually.
+ ///
+ private void InitializeComponent()
+ {
+ this.components = new System.ComponentModel.Container();
+ this.connStringPropertyGrid = new System.Windows.Forms.PropertyGrid();
+ this.buttonsFlowLayoutPanel = new System.Windows.Forms.FlowLayoutPanel();
+ this.testButton = new System.Windows.Forms.Button();
+ this.submitButton = new System.Windows.Forms.Button();
+ this.cancelButton = new System.Windows.Forms.Button();
+ this.providerTypeComboBox = new System.Windows.Forms.ComboBox();
+ this.dataSourceTypeLabel = new System.Windows.Forms.Label();
+ this.connStringResult = new System.Windows.Forms.TextBox();
+ this.connectionStringLabel = new System.Windows.Forms.Label();
+ this.progressTimer = new System.Windows.Forms.Timer(this.components);
+ this.statusStrip = new System.Windows.Forms.StatusStrip();
+ this.outputMessageTabControl = new System.Windows.Forms.TabControl();
+ this.connectionStringTab = new System.Windows.Forms.TabPage();
+ this.testResultTab = new System.Windows.Forms.TabPage();
+ this.testResultTextBox = new System.Windows.Forms.TextBox();
+ this.buttonsFlowLayoutPanel.SuspendLayout();
+ this.outputMessageTabControl.SuspendLayout();
+ this.connectionStringTab.SuspendLayout();
+ this.testResultTab.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // connStringPropertyGrid
+ //
+ this.connStringPropertyGrid.Location = new System.Drawing.Point(0, 39);
+ this.connStringPropertyGrid.Name = "connStringPropertyGrid";
+ this.connStringPropertyGrid.Size = new System.Drawing.Size(547, 300);
+ this.connStringPropertyGrid.TabIndex = 0;
+ //
+ // buttonsFlowLayoutPanel
+ //
+ this.buttonsFlowLayoutPanel.Controls.Add(this.testButton);
+ this.buttonsFlowLayoutPanel.Controls.Add(this.submitButton);
+ this.buttonsFlowLayoutPanel.Controls.Add(this.cancelButton);
+ this.buttonsFlowLayoutPanel.Location = new System.Drawing.Point(3, 447);
+ this.buttonsFlowLayoutPanel.Name = "buttonsFlowLayoutPanel";
+ this.buttonsFlowLayoutPanel.Size = new System.Drawing.Size(312, 34);
+ this.buttonsFlowLayoutPanel.TabIndex = 1;
+ //
+ // testButton
+ //
+ this.testButton.Location = new System.Drawing.Point(3, 3);
+ this.testButton.Name = "testButton";
+ this.testButton.Size = new System.Drawing.Size(75, 23);
+ this.testButton.TabIndex = 0;
+ this.testButton.Text = "Test";
+ this.testButton.UseVisualStyleBackColor = true;
+ this.testButton.Click += new System.EventHandler(this.TestButtonClick);
+ //
+ // submitButton
+ //
+ this.submitButton.Location = new System.Drawing.Point(84, 3);
+ this.submitButton.Name = "submitButton";
+ this.submitButton.Size = new System.Drawing.Size(75, 23);
+ this.submitButton.TabIndex = 1;
+ this.submitButton.Text = "Submit";
+ this.submitButton.UseVisualStyleBackColor = true;
+ this.submitButton.Click += new System.EventHandler(this.SubmitButtonClick);
+ //
+ // cancelButton
+ //
+ this.cancelButton.Location = new System.Drawing.Point(165, 3);
+ this.cancelButton.Name = "cancelButton";
+ this.cancelButton.Size = new System.Drawing.Size(75, 23);
+ this.cancelButton.TabIndex = 2;
+ this.cancelButton.Text = "Cancel";
+ this.cancelButton.UseVisualStyleBackColor = true;
+ this.cancelButton.Click += new System.EventHandler(this.CancelButtonClick);
+ //
+ // providerTypeComboBox
+ //
+ this.providerTypeComboBox.FormattingEnabled = true;
+ this.providerTypeComboBox.Location = new System.Drawing.Point(117, 12);
+ this.providerTypeComboBox.Name = "providerTypeComboBox";
+ this.providerTypeComboBox.Size = new System.Drawing.Size(195, 21);
+ this.providerTypeComboBox.TabIndex = 2;
+ this.providerTypeComboBox.SelectedIndexChanged += new System.EventHandler(this.ProviderTypeSelectedIndexChanged);
+ //
+ // dataSourceTypeLabel
+ //
+ this.dataSourceTypeLabel.Location = new System.Drawing.Point(3, 9);
+ this.dataSourceTypeLabel.Name = "dataSourceTypeLabel";
+ this.dataSourceTypeLabel.Size = new System.Drawing.Size(108, 23);
+ this.dataSourceTypeLabel.TabIndex = 3;
+ this.dataSourceTypeLabel.Text = "Data Source Type:";
+ this.dataSourceTypeLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
+ //
+ // connStringResult
+ //
+ this.connStringResult.Enabled = false;
+ this.connStringResult.Location = new System.Drawing.Point(0, 0);
+ this.connStringResult.Multiline = true;
+ this.connStringResult.Name = "connStringResult";
+ this.connStringResult.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
+ this.connStringResult.Size = new System.Drawing.Size(413, 74);
+ this.connStringResult.TabIndex = 4;
+ //
+ // connectionStringLabel
+ //
+ this.connectionStringLabel.Location = new System.Drawing.Point(12, 348);
+ this.connectionStringLabel.Name = "connectionStringLabel";
+ this.connectionStringLabel.Size = new System.Drawing.Size(100, 23);
+ this.connectionStringLabel.TabIndex = 5;
+ this.connectionStringLabel.Text = "Connection String:";
+ //
+ // progressTimer
+ //
+ this.progressTimer.Interval = 1000;
+ this.progressTimer.Tick += new System.EventHandler(this.ProgressTimerTick);
+ //
+ // statusStrip
+ //
+ this.statusStrip.Location = new System.Drawing.Point(0, 478);
+ this.statusStrip.Name = "statusStrip";
+ this.statusStrip.Size = new System.Drawing.Size(547, 22);
+ this.statusStrip.TabIndex = 6;
+ this.statusStrip.Text = "statusStrip1";
+ //
+ // testResultTab
+ //
+ this.outputMessageTabControl.Controls.Add(this.connectionStringTab);
+ this.outputMessageTabControl.Controls.Add(this.testResultTab);
+ this.outputMessageTabControl.Location = new System.Drawing.Point(118, 345);
+ this.outputMessageTabControl.Name = "testResultTab";
+ this.outputMessageTabControl.SelectedIndex = 0;
+ this.outputMessageTabControl.Size = new System.Drawing.Size(417, 100);
+ this.outputMessageTabControl.TabIndex = 7;
+ //
+ // tabPage1
+ //
+ this.connectionStringTab.Controls.Add(this.connStringResult);
+ this.connectionStringTab.Location = new System.Drawing.Point(4, 22);
+ this.connectionStringTab.Name = "tabPage1";
+ this.connectionStringTab.Padding = new System.Windows.Forms.Padding(3);
+ this.connectionStringTab.Size = new System.Drawing.Size(409, 74);
+ this.connectionStringTab.TabIndex = 0;
+ this.connectionStringTab.Text = "Connection String";
+ this.connectionStringTab.UseVisualStyleBackColor = true;
+ //
+ // tabPage2
+ //
+ this.testResultTab.Controls.Add(this.testResultTextBox);
+ this.testResultTab.Location = new System.Drawing.Point(4, 22);
+ this.testResultTab.Name = "tabPage2";
+ this.testResultTab.Padding = new System.Windows.Forms.Padding(3);
+ this.testResultTab.Size = new System.Drawing.Size(409, 74);
+ this.testResultTab.TabIndex = 1;
+ this.testResultTab.Text = "Test Result Message";
+ this.testResultTab.UseVisualStyleBackColor = true;
+ //
+ // testResultTextBox
+ //
+ this.testResultTextBox.Location = new System.Drawing.Point(-5, 0);
+ this.testResultTextBox.Multiline = true;
+ this.testResultTextBox.Name = "testResultTextBox";
+ this.testResultTextBox.Size = new System.Drawing.Size(418, 77);
+ this.testResultTextBox.TabIndex = 0;
+ //
+ // ConnectionStringDefinitionDialog
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(547, 500);
+ this.Controls.Add(this.outputMessageTabControl);
+ this.Controls.Add(this.statusStrip);
+ this.Controls.Add(this.connectionStringLabel);
+ this.Controls.Add(this.dataSourceTypeLabel);
+ this.Controls.Add(this.providerTypeComboBox);
+ this.Controls.Add(this.buttonsFlowLayoutPanel);
+ this.Controls.Add(this.connStringPropertyGrid);
+ this.Name = "ConnectionStringDefinitionDialog";
+ this.Text = "Set up Connection String";
+ this.buttonsFlowLayoutPanel.ResumeLayout(false);
+ this.outputMessageTabControl.ResumeLayout(false);
+ this.connectionStringTab.ResumeLayout(false);
+ this.connectionStringTab.PerformLayout();
+ this.testResultTab.ResumeLayout(false);
+ this.testResultTab.PerformLayout();
+ this.ResumeLayout(false);
+ this.PerformLayout();
+ }
+ private System.Windows.Forms.TabControl outputMessageTabControl;
+ private System.Windows.Forms.TextBox testResultTextBox;
+ private System.Windows.Forms.TabPage testResultTab;
+ private System.Windows.Forms.TabPage connectionStringTab;
+
+ private System.Windows.Forms.Timer progressTimer;
+ private System.Windows.Forms.StatusStrip statusStrip;
+ private System.Windows.Forms.TextBox connStringResult;
+ private System.Windows.Forms.Label connectionStringLabel;
+ private System.Windows.Forms.Label dataSourceTypeLabel;
+ private System.Windows.Forms.ComboBox providerTypeComboBox;
+ private System.Windows.Forms.Button cancelButton;
+ private System.Windows.Forms.Button submitButton;
+ private System.Windows.Forms.Button testButton;
+ private System.Windows.Forms.FlowLayoutPanel buttonsFlowLayoutPanel;
+ private System.Windows.Forms.PropertyGrid connStringPropertyGrid;
+ }
+}
diff --git a/src/AddIns/Misc/SharpServerTools/SharpDbTools/Src/Forms/ConnectionStringDefinitionDialog.cs b/src/AddIns/Misc/SharpServerTools/SharpDbTools/Src/Forms/ConnectionStringDefinitionDialog.cs
new file mode 100644
index 0000000000..560c9527e6
--- /dev/null
+++ b/src/AddIns/Misc/SharpServerTools/SharpDbTools/Src/Forms/ConnectionStringDefinitionDialog.cs
@@ -0,0 +1,257 @@
+//
+//
+//
+//
+// $Revision: 1684 $
+//
+
+using System;
+using System.Drawing;
+using System.Windows.Forms;
+using System.Collections.Generic;
+using System.Data.Common;
+using System.ComponentModel;
+
+using SharpDbTools.Data;
+
+namespace SharpDbTools.Forms
+{
+ ///
+ /// This class creates a dialog that can be used to create and test connection strings
+ /// that can be used with .net 2.0 DbProviders.
+ /// It utilises .net 2.0 configuration to discover any DbProviderFactories that are
+ /// installed and configured in machine.config, app.config or user.config using
+ /// standard .net 2.0 apis.
+ /// It then enables a user to browse the properties of each type of db connection,
+ /// set values for them and test the resulting connection string.
+ /// When the submit button is clicked the dialog is dismissed and the connection
+ /// string constructed is accessible through the ConnectionString property of the dialog.
+ ///
+ public partial class ConnectionStringDefinitionDialog
+ {
+ ToolStripProgressBar connectionTestProgressBar = new ToolStripProgressBar();
+ ConnectionTestBackgroundWorker testConnectionBackgroundWorker;
+ string resultMessage;
+ string invariantName;
+ ConnectionTestState connectionTestState = ConnectionTestState.UnTested;
+
+ public ConnectionStringDefinitionDialog()
+ {
+ //
+ // The InitializeComponent() call is required for Windows Forms designer support.
+ //
+ InitializeComponent();
+ this.connStringPropertyGrid.PropertyValueChanged +=
+ new PropertyValueChangedEventHandler(this.ConnStringAttributesViewPropertyValueChanged);
+ // add a ProgressBar to the statusString
+ this.statusStrip.Items.Add(connectionTestProgressBar);
+ this.connectionTestProgressBar.Step = 10;
+ this.connectionTestProgressBar.Minimum = 0;
+ this.connectionTestProgressBar.Maximum = 150;
+ }
+
+ public string InvariantName {
+ get {
+ return this.invariantName;
+ }
+ set {
+ this.invariantName = value;
+ }
+ }
+
+ public ConnectionTestState ConnectionTestState {
+ get {
+ return this.connectionTestState;
+ }
+ }
+
+ public string ResultMessage
+ {
+ get
+ {
+ return resultMessage;
+ }
+ set
+ {
+ resultMessage = value;
+ }
+ }
+
+ public DbConnectionStringBuilder ConnectionStringBuilder
+ {
+ get
+ {
+ return (DbConnectionStringBuilder)this.connStringPropertyGrid.SelectedObject;
+ }
+ }
+
+ public string ConnectionString
+ {
+ get
+ {
+ return ((DbConnectionStringBuilder)this.connStringPropertyGrid.SelectedObject).ConnectionString;
+ }
+ }
+
+ protected override void OnLoad(EventArgs e)
+ {
+ //
+ // set the PropertyGrid to browse the available DbProviders
+ //
+
+ base.OnLoad(e);
+
+ DbProvidersService service = DbProvidersService.GetDbProvidersService();
+ List names = service.Names;
+ this.providerTypeComboBox.DataSource = names;
+ this.connStringResult.Text = this.ConnectionString;
+ }
+
+ void CancelButtonClick(object sender, System.EventArgs e)
+ {
+ this.DialogResult = DialogResult.Cancel;
+ this.Close();
+ }
+
+ void ProviderTypeSelectedIndexChanged(object sender, System.EventArgs e)
+ {
+ string selection = (string)this.providerTypeComboBox.SelectedItem;
+ DbProvidersService service = DbProvidersService.GetDbProvidersService();
+ DbProviderFactory factory = service[selection];
+ DbConnectionStringBuilder builder = factory.CreateConnectionStringBuilder();
+ connStringPropertyGrid.SelectedObject = builder;
+ }
+
+ void ConnStringAttributesViewPropertyValueChanged(Object s, PropertyValueChangedEventArgs args)
+ {
+ // looking for changes to the ConnectionString property in the PropertyGrid
+ this.connStringResult.Text = this.ConnectionString;
+ this.outputMessageTabControl.SelectTab(this.connectionStringTab);
+ ResetTestResultTextBox();
+ }
+
+ void TestButtonClick(object sender, System.EventArgs e)
+ {
+ string dbTypeName = (string)this.providerTypeComboBox.SelectedItem;
+ testConnectionBackgroundWorker = new ConnectionTestBackgroundWorker(dbTypeName);
+ testConnectionBackgroundWorker.WorkerSupportsCancellation = false;
+ progressTimer.Enabled = true;
+ testConnectionBackgroundWorker.DoWork +=
+ new DoWorkEventHandler(this.TestConnectionBackgroundWorkerDoWork);
+ testConnectionBackgroundWorker.RunWorkerCompleted +=
+ new RunWorkerCompletedEventHandler(TestConnectionRunWorkerComplete);
+ testConnectionBackgroundWorker.RunWorkerAsync();
+ }
+
+ void ProgressTimerTick(object sender, System.EventArgs e)
+ {
+ this.BeginInvoke(new EventHandler(UpdateProgressBar));
+ }
+
+ void UpdateProgressBar(object sender, EventArgs e)
+ {
+ ToolStripProgressBar p = connectionTestProgressBar;
+ if (p.Value == p.Maximum) p.Value = 0;
+ p.PerformStep();
+ }
+
+ void SetTestResultTextBox()
+ {
+ this.testResultTextBox.Text = ResultMessage;
+ this.outputMessageTabControl.SelectTab(this.testResultTab);
+ }
+
+ void ResetTestResultTextBox()
+ {
+ this.testResultTextBox.Text = "";
+ this.connectionTestState = ConnectionTestState.UnTested;
+ }
+
+ void TestConnectionBackgroundWorkerDoWork(object sender, DoWorkEventArgs e)
+ {
+ DbConnection connection = null;
+ try
+ {
+ // get the current name
+
+ ConnectionTestBackgroundWorker bw = sender as ConnectionTestBackgroundWorker;
+ string currentDbTypeName = bw.DatabaseType;
+
+ // get the DbProviderFactory for this name
+
+ DbProvidersService service = DbProvidersService.GetDbProvidersService();
+ DbProviderFactory factory = service[currentDbTypeName];
+
+ // get a connection object or this factory
+
+ connection = factory.CreateConnection();
+ connection.ConnectionString = this.ConnectionString;
+
+ connection.Open();
+ e.Result = "Connection Succeeded";
+ connectionTestState = ConnectionTestState.TestSucceeded;
+ }
+ catch(Exception ex)
+ {
+ e.Result = "Connection Failed: " + ex.Message;
+ connectionTestState = ConnectionTestState.TestFailed;
+ }
+ finally
+ {
+ if (connection != null)
+ {
+ connection.Close();
+ }
+ }
+ }
+
+ void TestConnectionRunWorkerComplete(object sender, RunWorkerCompletedEventArgs args)
+ {
+ ResultMessage = args.Result as string;
+ this.Invoke(new EventHandler(TestConnectionCompleted));
+ }
+
+ void TestConnectionCompleted(object sender, EventArgs args)
+ {
+ progressTimer.Enabled = false;
+ connectionTestProgressBar.Value = 0;
+ SetTestResultTextBox();
+ testConnectionBackgroundWorker.Dispose();
+ }
+
+ void SubmitButtonClick(object sender, System.EventArgs e)
+ {
+ string name = (string)this.providerTypeComboBox.SelectedItem;
+ DbProvidersService service = DbProvidersService.GetDbProvidersService();
+ this.InvariantName = service.GetInvariantName(name);
+
+ this.DialogResult = DialogResult.OK;
+ this.Close();
+ }
+ }
+
+ public enum ConnectionTestState
+ {
+ UnTested,
+ TestFailed,
+ TestSucceeded
+ }
+
+ class ConnectionTestBackgroundWorker: BackgroundWorker
+ {
+ private string dbTypeName;
+
+ public ConnectionTestBackgroundWorker(string dbTypeName): base()
+ {
+ this.dbTypeName = dbTypeName;
+ }
+
+ public string DatabaseType
+ {
+ get
+ {
+ return dbTypeName;
+ }
+ }
+ }
+}
diff --git a/src/AddIns/Misc/SharpServerTools/SharpDbTools/Src/Forms/ConnectionStringDefinitionDialog.resx b/src/AddIns/Misc/SharpServerTools/SharpDbTools/Src/Forms/ConnectionStringDefinitionDialog.resx
new file mode 100644
index 0000000000..157d9061d2
--- /dev/null
+++ b/src/AddIns/Misc/SharpServerTools/SharpDbTools/Src/Forms/ConnectionStringDefinitionDialog.resx
@@ -0,0 +1,126 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ 247, 17
+
+
+ 371, 17
+
+
\ No newline at end of file
diff --git a/src/AddIns/Misc/SharpServerTools/SharpDbTools/Src/Forms/DatabaseExplorerTreeNode.cs b/src/AddIns/Misc/SharpServerTools/SharpDbTools/Src/Forms/DatabaseExplorerTreeNode.cs
new file mode 100644
index 0000000000..2d1a04dea4
--- /dev/null
+++ b/src/AddIns/Misc/SharpServerTools/SharpDbTools/Src/Forms/DatabaseExplorerTreeNode.cs
@@ -0,0 +1,147 @@
+/*
+ * User: dickon
+ * Date: 23/09/2006
+ * Time: 22:50
+ *
+ */
+
+using System;
+using System.Windows.Forms;
+using System.Collections.Generic;
+
+using ICSharpCode.Core;
+
+using SharpDbTools.Data;
+using SharpServerTools.Forms;
+
+namespace SharpDbTools.Forms
+{
+ ///
+ /// Description of DatabaseExplorerNode.
+ /// Hold minimal state - access state through the DbModelInfoService
+ ///
+ public class DatabaseExplorerTreeNode: TreeNode, IRebuildable, IRequiresRebuildSource
+ {
+ public DatabaseExplorerTreeNode(): base("Database Explorer")
+ {
+ ContextMenuStrip cMenu = new ContextMenuStrip();
+ ToolStripMenuItem addConnectionMenuItem =
+ new ToolStripMenuItem("Add Connection");
+ addConnectionMenuItem.Click += new EventHandler(AddDbConnectionClickHandler);
+
+ ToolStripMenuItem deleteConnectionMenuItem =
+ new ToolStripMenuItem("Delete Connection");
+ deleteConnectionMenuItem.Click += new EventHandler(DeleteDbConnectionClickHandler);
+
+ ToolStripMenuItem saveMetadataMenuItem =
+ new ToolStripMenuItem("Save All");
+ saveMetadataMenuItem.Click += new EventHandler(SaveDbModelInfoClickHandler);
+
+
+ cMenu.Items.AddRange(new ToolStripMenuItem[]
+ {
+ addConnectionMenuItem,
+ deleteConnectionMenuItem,
+ saveMetadataMenuItem
+ }
+ );
+ this.ContextMenuStrip = cMenu;
+ }
+
+ public void Rebuild()
+ {
+ this.Nodes.Clear();
+ foreach (string name in DbModelInfoService.Names) {
+ LoggingService.Debug(this.GetType().ToString() + " getting DbModelInfoTreeNode for node: " + name);
+ DbModelInfoTreeNode dbModelInfoNode = CreateDbModelInfoNode(name);
+ dbModelInfoNode.RebuildRequiredEvent += new RebuildRequiredEventHandler(RebuildRequiredNotify);
+ this.Nodes.Add(dbModelInfoNode);
+ }
+ }
+
+ public event RebuildRequiredEventHandler RebuildRequiredEvent;
+
+ ///
+ /// DatabaseExplorerTreeNode chucks away any existing Nodes and recreates its tree when it
+ /// is triggered.
+ ///
+ ///
+ ///
+ private void RebuildRequiredNotify(object sender, RebuildRequiredEventArgs e)
+ {
+ // adding this node because it wants to be rebuilt.
+ e.AddNode(this);
+ this.FireRebuildRequired(this, e);
+ }
+
+ private void FireRebuildRequired(object sender, RebuildRequiredEventArgs e)
+ {
+ if (this.RebuildRequiredEvent != null) {
+ RebuildRequiredEvent(this, e);
+ }
+ }
+
+ private DbModelInfoTreeNode CreateDbModelInfoNode(string name)
+ {
+ return new DbModelInfoTreeNode(name);
+ }
+
+ ///
+ /// Uses a dialog to get the logical name of a new Connection then
+ /// adds a new DbModelInfo for it to the cache and updates the DatabaseServer
+ /// Tree.
+ ///
+ ///
+ ///
+
+ private void AddDbConnectionClickHandler(object sender, EventArgs e)
+ {
+ LoggingService.Debug("add connection clicked");
+
+ // get the logical name of the new connection
+
+ string logicalName = null;
+ using (GetConnectionLogicalNameDialog dialog = new GetConnectionLogicalNameDialog()) {
+ dialog.ShowDialog();
+ logicalName = dialog.LogicalConnectionName;
+ }
+ if (logicalName.Equals("") || logicalName == null) return;
+
+ LoggingService.Debug("name received is: " + logicalName);
+
+ // add a new DbModelInfo to the cache
+
+ DbModelInfoService.Add(logicalName, null, null);
+
+ // rebuild the database server node
+
+ RebuildRequiredEventArgs e1 = new RebuildRequiredEventArgs();
+ e1.AddNode(this as IRebuildable);
+ this.FireRebuildRequired(this, e1);
+ }
+
+ private void DeleteDbConnectionClickHandler(object sender, EventArgs e)
+ {
+ LoggingService.Debug("delete connection clicked");
+ }
+
+ private void SaveDbModelInfoClickHandler(object sender, EventArgs e)
+ {
+ // save each DbModelInfo separately, confirming overwrite where necessary
+
+ LoggingService.Debug("save all metadata clicked - will iterate through each and attempt to save");
+ IList names = DbModelInfoService.Names;
+ foreach (string name in names) {
+ bool saved = DbModelInfoService.SaveToFile(name, false);
+ if (!saved) {
+ DialogResult result = MessageBox.Show("Overwrite existing file for connection: " + name + "?",
+ "File exists for connection", MessageBoxButtons.YesNo,
+ MessageBoxIcon.Question, MessageBoxDefaultButton.Button1);
+ if (result.Equals(DialogResult.Yes)) {
+ DbModelInfoService.SaveToFile(name, true);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/AddIns/Misc/SharpServerTools/SharpDbTools/Src/Forms/DbModelInfoTreeNode.cs b/src/AddIns/Misc/SharpServerTools/SharpDbTools/Src/Forms/DbModelInfoTreeNode.cs
new file mode 100644
index 0000000000..30a2a2acf1
--- /dev/null
+++ b/src/AddIns/Misc/SharpServerTools/SharpDbTools/Src/Forms/DbModelInfoTreeNode.cs
@@ -0,0 +1,210 @@
+/*
+ * User: dickon
+ * Date: 23/09/2006
+ * Time: 23:37
+ *
+ */
+
+using System;
+using System.Windows.Forms;
+using System.Data.Common;
+
+using ICSharpCode.Core;
+
+using SharpServerTools.Forms;
+
+using SharpDbTools.Data;
+
+namespace SharpDbTools.Forms
+{
+ ///
+ /// Renders a view of the metadata and connection properties for a single
+ /// database connection. It is an IRequiresRebuildSource and can emit
+ /// RequiresRebuildEvents when the metadata etc are changed, but the
+ /// DatabaseExplorerTreeNode disposes of these and constructs new ones
+ /// when this occurs, so it is not an IRebuildable
+ ///
+ public class DbModelInfoTreeNode: TreeNode, IRequiresRebuildSource
+ {
+ public DbModelInfoTreeNode(string name): base(name)
+ {
+ // create and add the menustrip for this node
+
+ NodeAwareContextMenuStrip cMenu = new NodeAwareContextMenuStrip(this);
+
+ // create menu items
+
+ ToolStripMenuItem setConnectionStringMenuItem =
+ new ToolStripMenuItem("Set Connection String");
+ setConnectionStringMenuItem.Click += new EventHandler(SetConnectionStringOnDbModelInfoClickHandler);
+
+ ToolStripMenuItem loadMetadataFromConnectionMenuItem =
+ new ToolStripMenuItem("Load Metadata from Connection");
+ loadMetadataFromConnectionMenuItem.Click += new EventHandler(LoadMetadataFromConnectionClickHandler);
+
+ ToolStripMenuItem loadMetadataFromFileMenuItem =
+ new ToolStripMenuItem("Load Metadata from File");
+ loadMetadataFromFileMenuItem.Click += new EventHandler(LoadMetadataFromFileClickHandler);
+
+
+ cMenu.Items.AddRange(new ToolStripMenuItem[]
+ {
+ setConnectionStringMenuItem,
+ loadMetadataFromConnectionMenuItem,
+ loadMetadataFromFileMenuItem
+ });
+
+ this.ContextMenuStrip = cMenu;
+ this.Nodes.Clear();
+ TreeNode connectionPropsNode = CreateConnectionPropertiesNode(this.LogicalConnectionName);
+ TreeNode dbNode = CreateMetaDataNode(this.LogicalConnectionName);
+ this.Nodes.Add(connectionPropsNode);
+ this.Nodes.Add(dbNode);
+ }
+
+ public string LogicalConnectionName {
+ get {
+ return this.Text;
+ }
+ }
+
+ public event RebuildRequiredEventHandler RebuildRequiredEvent;
+
+ protected void FireRebuildRequired()
+ {
+ // HERE: the null eventargs indicates no desire to be rebuilt - is this correct?
+ if (RebuildRequiredEvent != null) {
+ // This object does not want to be rebuilt - it is discarded when there is
+ // a change in the underlying model. So, an event is posted without a ref
+ // to this object.
+ RebuildRequiredEventArgs eventArgs = new RebuildRequiredEventArgs();
+ RebuildRequiredEvent(this, eventArgs);
+ }
+ }
+
+ private TreeNode CreateConnectionPropertiesNode(string name)
+ {
+ // create sub TreeNodes for the connection string and invariant name if they exist
+ LoggingService.Debug("Looking for a Db Model Info for connection with name: " + name);
+ DbModelInfo modelInfo = DbModelInfoService.GetDbModelInfo(name);
+
+ if (modelInfo == null) {
+ LoggingService.Error("could not find a logical connection named: " + name);
+ throw new ArgumentException("this logical connection name is not defined: " + name);
+ }
+ string connectionString = modelInfo.ConnectionString;
+ string invariantName = modelInfo.InvariantName;
+
+ TreeNode attributesNode = new TreeNode("Connection Properties");
+
+ if (connectionString != null) {
+ TreeNode cstringNode = new TreeNode("Connection String: " + connectionString);
+ attributesNode.Nodes.Add(cstringNode);
+ }
+
+ if (invariantName != null) {
+ TreeNode invNameNode = new TreeNode("Invariant Name: " + invariantName);
+ attributesNode.Nodes.Add(invNameNode);
+ }
+
+ return attributesNode;
+ }
+
+ private TreeNode CreateMetaDataNode(string name)
+ {
+ LoggingService.Debug("creating metadata tree for connection with name: " + name);
+ TreeNode node = null;
+ // get the invariant name from the name, then get the FormsArtefactFactory
+ DbModelInfo modelInfo = DbModelInfoService.GetDbModelInfo(name);
+
+ if (modelInfo == null) {
+ LoggingService.Error("could not find a logical connection named: " + name);
+ throw new ArgumentException("this logical connection name is not defined: " + name);
+ }
+
+ string invariantName = modelInfo.InvariantName;
+ LoggingService.Debug("got invariant name: " + invariantName + " for connection name: " + name);
+
+ try {
+ LoggingService.Debug(this.GetType().ToString()
+ + ": getting forms info for name: "
+ + name + " and invariant name: "
+ + invariantName);
+ FormsArtefactFactory factory = FormsArtefactFactories.GetFactory(invariantName);
+ node = factory.CreateMetaDataNode(name);
+ } catch(ArgumentException e) {
+ LoggingService.Debug(this.GetType().ToString()
+ + " failed to create metadata node for connection: "
+ + name + "\n"
+ + e.Message + "\n"
+ + e.GetType().ToString());
+ node = new TreeNode("No Metadata");
+ }
+ return node;
+ }
+
+ ///
+ /// Uses a dialog to get the logical name of a new Connection then
+ /// adds a new DbModelInfo for it to the cache and updates the DatabaseServer
+ /// Tree.
+ ///
+ ///
+ ///
+
+ private void SetConnectionStringOnDbModelInfoClickHandler(object sender, EventArgs e)
+ {
+ string connectionLogicalName = this.Text;
+ LoggingService.Debug("add connection string clicked for item with name: " + connectionLogicalName);
+
+ // use the ConnectionStringDefinitionDialog to get a connection string and invariant name
+ ConnectionStringDefinitionDialog definitionDialog = new ConnectionStringDefinitionDialog();
+ DialogResult result = definitionDialog.ShowDialog();
+
+ // if the dialog was cancelled then do nothing
+ if (result == DialogResult.Cancel) {
+ return;
+ }
+
+ // if the dialog was submitted and connection string has changed then clear the DbModelInfo metadata
+ // note that is is not required for the Connection string to be valid - it may be work
+ // in progress and a user might want to save a partially formed connection string
+
+ DbModelInfo dbModelInfo = DbModelInfoService.GetDbModelInfo(connectionLogicalName);
+ string connectionString = dbModelInfo.ConnectionString;
+ string newConnectionString = definitionDialog.ConnectionString;
+
+ if (newConnectionString == null) {
+ return;
+ }
+
+ dbModelInfo.ConnectionString = newConnectionString;
+ dbModelInfo.InvariantName = definitionDialog.InvariantName;
+
+ // rebuild the database explorer node
+ this.FireRebuildRequired();
+ }
+
+ private void LoadMetadataFromFileClickHandler(object sender, EventArgs e)
+ {
+ LoggingService.Debug("load metadata from file clicked");
+ string logicalConnectionName = this.Text;
+ DbModelInfoService.LoadFromFile(logicalConnectionName);
+ this.FireRebuildRequired();
+ }
+
+ private void LoadMetadataFromConnectionClickHandler(object sender, EventArgs args)
+ {
+ string connectionLogicalName = this.Text;
+ LoggingService.Debug("load metadata from connection clicked for connection with name: "
+ + connectionLogicalName);
+ try {
+ DbModelInfoService.LoadMetadataFromConnection(connectionLogicalName);
+ }
+ catch(DbException e) {
+ MessageService.ShowError(e,
+ "An Exception was thrown while trying to connect to: " + connectionLogicalName);
+ }
+ this.FireRebuildRequired();
+ }
+ }
+}
diff --git a/src/AddIns/Misc/SharpServerTools/SharpDbTools/Src/Forms/FormsArtefactFactories.cs b/src/AddIns/Misc/SharpServerTools/SharpDbTools/Src/Forms/FormsArtefactFactories.cs
new file mode 100644
index 0000000000..5ab616f662
--- /dev/null
+++ b/src/AddIns/Misc/SharpServerTools/SharpDbTools/Src/Forms/FormsArtefactFactories.cs
@@ -0,0 +1,55 @@
+/*
+ * User: dickon
+ * Date: 17/09/2006
+ * Time: 09:33
+ *
+ */
+
+using System;
+using ICSharpCode.Core;
+
+
+namespace SharpDbTools.Forms
+{
+ ///
+ /// Description of FormsArtefactFactories.
+ ///
+ public class FormsArtefactFactories
+ {
+ public FormsArtefactFactories()
+ {
+ }
+
+ public static FormsArtefactFactory GetFactory(string invariantName)
+ {
+ LoggingService.Debug("Looking for FormsArtefactFactory for: " + invariantName);
+
+ // to test this base it on hardcoded strings for the type of the factory
+
+ // TODO: drive this from the AddIn tree
+ switch (invariantName)
+ {
+ case "System.Data.OracleClient":
+ Type type = Type.GetType("SharpDbTools.Oracle.Forms.OracleFormsArtefactFactory, OracleDbToolsProvider");
+ FormsArtefactFactory factory = (FormsArtefactFactory)Activator.CreateInstance(type);
+ LoggingService.Debug("Found FormsArtefactFactory for: " + invariantName);
+ return factory;
+ default:
+ LoggingService.Debug("Failed to find FormsArtefactFactory for: " + invariantName);
+ throw new ArgumentException("There is no FormsArtefactFactory for invariant name: " +
+ invariantName);
+ }
+
+
+ // TODO: retrieve the relevant factory from file-base config
+ // TODO: >>>>>>>>>>>>>>>>>>> NEXT: retrieve an XML element with mapping
+ // from invariant name to class name of FormsArtefactProvider
+ // options include specific config file or use of .net process config.
+
+ // 1. load the config file for DbTools FormsArtefacts
+ // 2. find the string name of the type of the FormsArtefactsFactory implementation
+ // corresponding to invariatName
+ // 3. use Type.GetType to create an instance of it and return it to the caller
+ }
+ }
+}
diff --git a/src/AddIns/Misc/SharpServerTools/SharpDbTools/Src/Forms/FormsArtefactFactory.cs b/src/AddIns/Misc/SharpServerTools/SharpDbTools/Src/Forms/FormsArtefactFactory.cs
new file mode 100644
index 0000000000..6c3ad26410
--- /dev/null
+++ b/src/AddIns/Misc/SharpServerTools/SharpDbTools/Src/Forms/FormsArtefactFactory.cs
@@ -0,0 +1,24 @@
+/*
+ * User: dickon
+ * Date: 17/09/2006
+ * Time: 23:47
+ *
+ */
+
+using System;
+using System.Windows.Forms;
+
+namespace SharpDbTools.Forms
+{
+ ///
+ /// Description of FormsArtefactFactory.
+ ///
+ public abstract class FormsArtefactFactory
+ {
+ public FormsArtefactFactory()
+ {
+ }
+
+ public abstract TreeNode CreateMetaDataNode(string name);
+ }
+}
diff --git a/src/AddIns/Misc/SharpServerTools/SharpDbTools/Src/Forms/GetConnectionLogicalNameDialog.Designer.cs b/src/AddIns/Misc/SharpServerTools/SharpDbTools/Src/Forms/GetConnectionLogicalNameDialog.Designer.cs
new file mode 100644
index 0000000000..bf888294c5
--- /dev/null
+++ b/src/AddIns/Misc/SharpServerTools/SharpDbTools/Src/Forms/GetConnectionLogicalNameDialog.Designer.cs
@@ -0,0 +1,100 @@
+/*
+ * User: dickon
+ * Date: 04/08/2006
+ * Time: 22:21
+ */
+namespace SharpDbTools.Forms
+{
+ partial class GetConnectionLogicalNameDialog : System.Windows.Forms.Form
+ {
+ ///
+ /// Designer variable used to keep track of non-visual components.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Disposes resources used by the form.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing) {
+ if (components != null) {
+ components.Dispose();
+ }
+ }
+ base.Dispose(disposing);
+ }
+
+ ///
+ /// This method is required for Windows Forms designer support.
+ /// Do not change the method contents inside the source code editor. The Forms designer might
+ /// not be able to load this method if it was changed manually.
+ ///
+ private void InitializeComponent()
+ {
+ this.connectionName = new System.Windows.Forms.TextBox();
+ this.connectionNameOKButton = new System.Windows.Forms.Button();
+ this.connectionNameCancelButton = new System.Windows.Forms.Button();
+ this.label1 = new System.Windows.Forms.Label();
+ this.SuspendLayout();
+ //
+ // connectionName
+ //
+ this.connectionName.Location = new System.Drawing.Point(12, 33);
+ this.connectionName.MaxLength = 30;
+ this.connectionName.Name = "connectionName";
+ this.connectionName.Size = new System.Drawing.Size(292, 21);
+ this.connectionName.TabIndex = 0;
+ //
+ // connectionNameOKButton
+ //
+ this.connectionNameOKButton.Location = new System.Drawing.Point(66, 70);
+ this.connectionNameOKButton.Name = "connectionNameOKButton";
+ this.connectionNameOKButton.Size = new System.Drawing.Size(75, 23);
+ this.connectionNameOKButton.TabIndex = 1;
+ this.connectionNameOKButton.Text = "OK";
+ this.connectionNameOKButton.UseVisualStyleBackColor = true;
+ this.connectionNameOKButton.Click += new System.EventHandler(this.ConnectionNameOKButtonClick);
+ //
+ // connectionNameCancelButton
+ //
+ this.connectionNameCancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+ this.connectionNameCancelButton.Location = new System.Drawing.Point(171, 70);
+ this.connectionNameCancelButton.Name = "connectionNameCancelButton";
+ this.connectionNameCancelButton.Size = new System.Drawing.Size(75, 23);
+ this.connectionNameCancelButton.TabIndex = 2;
+ this.connectionNameCancelButton.Text = "Cancel";
+ this.connectionNameCancelButton.UseVisualStyleBackColor = true;
+ this.connectionNameCancelButton.Click += new System.EventHandler(this.ConnectionNameCancelButtonClick);
+ //
+ // label1
+ //
+ this.label1.Location = new System.Drawing.Point(12, 9);
+ this.label1.Name = "label1";
+ this.label1.Size = new System.Drawing.Size(259, 23);
+ this.label1.TabIndex = 3;
+ this.label1.Text = "Please provide the name for your db connection:";
+ //
+ // GetConnectionLogicalNameDialog
+ //
+ this.AcceptButton = this.connectionNameOKButton;
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.CancelButton = this.connectionNameCancelButton;
+ this.ClientSize = new System.Drawing.Size(316, 114);
+ this.Controls.Add(this.label1);
+ this.Controls.Add(this.connectionNameCancelButton);
+ this.Controls.Add(this.connectionNameOKButton);
+ this.Controls.Add(this.connectionName);
+ this.Name = "GetConnectionLogicalNameDialog";
+ this.Text = "Connection Name";
+ this.ResumeLayout(false);
+ this.PerformLayout();
+ }
+ private System.Windows.Forms.TextBox connectionName;
+ private System.Windows.Forms.Label label1;
+ private System.Windows.Forms.Button connectionNameCancelButton;
+ private System.Windows.Forms.Button connectionNameOKButton;
+ }
+}
diff --git a/src/AddIns/Misc/SharpServerTools/SharpDbTools/Src/Forms/GetConnectionLogicalNameDialog.cs b/src/AddIns/Misc/SharpServerTools/SharpDbTools/Src/Forms/GetConnectionLogicalNameDialog.cs
new file mode 100644
index 0000000000..b485d5180b
--- /dev/null
+++ b/src/AddIns/Misc/SharpServerTools/SharpDbTools/Src/Forms/GetConnectionLogicalNameDialog.cs
@@ -0,0 +1,46 @@
+/*
+ * User: dickon
+ * Date: 04/08/2006
+ * Time: 22:21
+ */
+
+using System;
+using System.Drawing;
+using System.Windows.Forms;
+
+namespace SharpDbTools.Forms
+{
+ ///
+ /// Description of GetConnectionLogicalNameDialog.
+ ///
+ public partial class GetConnectionLogicalNameDialog
+ {
+ public GetConnectionLogicalNameDialog()
+ {
+ //
+ // The InitializeComponent() call is required for Windows Forms designer support.
+ //
+ InitializeComponent();
+
+ //
+ // TODO: Add constructor code after the InitializeComponent() call.
+ //
+ }
+
+ public string LogicalConnectionName {
+ get {
+ return this.connectionName.Text;
+ }
+ }
+
+ void ConnectionNameOKButtonClick(object sender, System.EventArgs e)
+ {
+ this.Close();
+ }
+
+ void ConnectionNameCancelButtonClick(object sender, System.EventArgs e)
+ {
+ this.Close();
+ }
+ }
+}
diff --git a/src/AddIns/Misc/SharpServerTools/SharpDbTools/Src/Forms/GetConnectionLogicalNameDialog.resx b/src/AddIns/Misc/SharpServerTools/SharpDbTools/Src/Forms/GetConnectionLogicalNameDialog.resx
new file mode 100644
index 0000000000..7080a7d118
--- /dev/null
+++ b/src/AddIns/Misc/SharpServerTools/SharpDbTools/Src/Forms/GetConnectionLogicalNameDialog.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/src/AddIns/Misc/SharpServerTools/SharpDbTools/Src/Forms/TableDescribeViewContent.cs b/src/AddIns/Misc/SharpServerTools/SharpDbTools/Src/Forms/TableDescribeViewContent.cs
new file mode 100644
index 0000000000..b17a45151b
--- /dev/null
+++ b/src/AddIns/Misc/SharpServerTools/SharpDbTools/Src/Forms/TableDescribeViewContent.cs
@@ -0,0 +1,72 @@
+/*
+ * User: dickon
+ * Date: 06/09/2006
+ * Time: 08:43
+ *
+ */
+
+using System;
+using System.Data;
+using System.Windows.Forms;
+
+using ICSharpCode.SharpDevelop.Gui;
+using SharpDbTools.Data;
+
+
+namespace SharpDbTools.Forms
+{
+ ///
+ /// Description of TableDescribeViewContent.
+ ///
+ public class TableDescribeViewContent : AbstractViewContent
+ {
+ DataTable tableInfo;
+ DataGridView tableInfoDataGridView;
+
+
+ public TableDescribeViewContent(DataTable tableInfo, string tableName) : base("table: " + tableName)
+ {
+ this.tableInfo = tableInfo;
+ this.tableInfoDataGridView = new DataGridView();
+ DataGridView v = this.tableInfoDataGridView;
+
+ v.AutoGenerateColumns = false;
+ v.AutoSize = true;
+
+ v.DataSource = this.tableInfo;
+ //v.DataMember = TableNames.Columns;
+
+ string[] fieldsToDisplay = ColumnNames.TableTableFieldsToDisplay;
+ string[] fieldColumnNames = ColumnNames.TableTableFieldsColumnHeaders;
+ for (int i = 0; i < fieldsToDisplay.Length; i++ ) {
+ DataGridViewColumn c = new DataGridViewTextBoxColumn();
+ c.DataPropertyName = fieldsToDisplay[i];
+ c.Name = fieldColumnNames[i];
+ v.Columns.Add(c);
+ }
+ v.AllowUserToAddRows = false;
+ v.AllowUserToDeleteRows = false;
+ v.AllowUserToResizeRows = false;
+ v.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.DisplayedCells;
+ v.AutoResizeColumns();
+ }
+
+ public override System.Windows.Forms.Control Control {
+ get {
+ return this.tableInfoDataGridView;
+ }
+ }
+
+ public override bool IsReadOnly {
+ get {
+ return true;
+ }
+ }
+
+ public override bool IsViewOnly {
+ get {
+ return true;
+ }
+ }
+ }
+}
diff --git a/src/AddIns/Misc/SharpServerTools/SharpServerTools.addin b/src/AddIns/Misc/SharpServerTools/SharpServerTools.addin
new file mode 100644
index 0000000000..48a5b7bd66
--- /dev/null
+++ b/src/AddIns/Misc/SharpServerTools/SharpServerTools.addin
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+