├── .gitattributes ├── .gitignore ├── Changelog.md ├── LICENSE ├── README.md └── Source ├── .nuget └── NuGet.Config ├── SqlTodoExplorer.Tests.Client ├── App.config ├── FakePresentationDataService.cs ├── Program.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Settings.Designer.cs │ └── Settings.settings └── SqlTodoExplorer.Tests.Client.csproj ├── SqlTodoExplorer.Tests ├── Presentation │ └── When_navigate_todo_item.cs ├── Properties │ └── AssemblyInfo.cs ├── Services │ ├── TodoPatternServiceTests.cs │ └── When_read_RegexPattern_property_of_a_TodoPattern.cs ├── SqlTodoExplorer.Tests.csproj └── packages.config ├── SqlTodoExplorer.sln └── SqlTodoExplorer ├── AssemblyInfo.cs ├── Connect.cs ├── DamnTools.SqlTodoExplorer.AddIn ├── Presentation ├── Helpers │ └── ToolStripRender.cs ├── ISqlTodoExplorerView.cs ├── Model │ ├── Data │ │ ├── DatabaseDataRecord.cs │ │ ├── RoutineDataRecord.cs │ │ └── RoutineType.cs │ ├── DatabaseName.cs │ ├── FilterItemType.cs │ ├── GroupByItemType.cs │ ├── IPresentationDataService.cs │ ├── NodeType.cs │ ├── PresentationDataService.cs │ └── TreeNodeMetaData.cs ├── SqlTodoExplorerPresenter.cs ├── SqlTodoExplorerView.Designer.cs ├── SqlTodoExplorerView.cs ├── SqlTodoExplorerView.en.resx ├── SqlTodoExplorerView.it-IT.resx ├── SqlTodoExplorerView.resx └── WartermarkTextBox.cs ├── Properties ├── Resources.Designer.cs ├── Resources.en.resx ├── Resources.it.resx └── Resources.resx ├── ReadMe.txt ├── Resources ├── 1.bmp ├── DefaultTodoPatterns.xml ├── PropertyIcon.png ├── Textfile_818_16x.png ├── XMLFile_828_16x.png ├── arrow_Sync_16xLG.png ├── collapse.gif ├── expand.gif └── refresh_16xLG.png ├── Services ├── DbEnumTypeHelper.cs ├── IScriptService.cs ├── IServerConnectionService.cs ├── IServerGateway.cs ├── ITodoExplorerManager.cs ├── ITodoPattern.cs ├── ITodoPatternService.cs ├── IWindowsManager.cs ├── Resources.Designer.cs ├── Resources.resx ├── Routine.cs ├── RoutineType.cs ├── ScriptService.cs ├── ServerConnectionInfo.cs ├── ServerConnectionService.cs ├── SmoServerGateway.cs ├── SqlDataReaderEx.cs ├── TodoExplorer.cs ├── TodoExplorerManager.cs ├── TodoItem.cs ├── TodoPattern.cs ├── TodoPatternService.cs └── WindowsManager.cs └── SqlTodoExplorer.csproj /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.sln.docstates 8 | 9 | # Build results 10 | [Dd]ebug/ 11 | [Dd]ebugPublic/ 12 | [Rr]elease/ 13 | x64/ 14 | build/ 15 | bld/ 16 | [Bb]in/ 17 | [Oo]bj/ 18 | 19 | # MSTest test Results 20 | [Tt]est[Rr]esult*/ 21 | [Bb]uild[Ll]og.* 22 | 23 | #NUNIT 24 | *.VisualState.xml 25 | TestResult.xml 26 | 27 | # Build Results of an ATL Project 28 | [Dd]ebugPS/ 29 | [Rr]eleasePS/ 30 | dlldata.c 31 | 32 | *_i.c 33 | *_p.c 34 | *_i.h 35 | *.ilk 36 | *.meta 37 | *.obj 38 | *.pch 39 | *.pdb 40 | *.pgc 41 | *.pgd 42 | *.rsp 43 | *.sbr 44 | *.tlb 45 | *.tli 46 | *.tlh 47 | *.tmp 48 | *.tmp_proj 49 | *.log 50 | *.vspscc 51 | *.vssscc 52 | .builds 53 | *.pidb 54 | *.svclog 55 | *.scc 56 | 57 | # Chutzpah Test files 58 | _Chutzpah* 59 | 60 | # Visual C++ cache files 61 | ipch/ 62 | *.aps 63 | *.ncb 64 | *.opensdf 65 | *.sdf 66 | *.cachefile 67 | 68 | # Visual Studio profiler 69 | *.psess 70 | *.vsp 71 | *.vspx 72 | 73 | # TFS 2012 Local Workspace 74 | $tf/ 75 | 76 | # Guidance Automation Toolkit 77 | *.gpState 78 | 79 | # ReSharper is a .NET coding add-in 80 | _ReSharper*/ 81 | *.[Rr]e[Ss]harper 82 | *.DotSettings.user 83 | 84 | # JustCode is a .NET coding addin-in 85 | .JustCode 86 | 87 | # TeamCity is a build add-in 88 | _TeamCity* 89 | 90 | # DotCover is a Code Coverage Tool 91 | *.dotCover 92 | 93 | # NCrunch 94 | *.ncrunch* 95 | _NCrunch_* 96 | .*crunch*.local.xml 97 | 98 | # MightyMoose 99 | *.mm.* 100 | AutoTest.Net/ 101 | 102 | # Web workbench (sass) 103 | .sass-cache/ 104 | 105 | # Installshield output folder 106 | [Ee]xpress/ 107 | 108 | # DocProject is a documentation generator add-in 109 | DocProject/buildhelp/ 110 | DocProject/Help/*.HxT 111 | DocProject/Help/*.HxC 112 | DocProject/Help/*.hhc 113 | DocProject/Help/*.hhk 114 | DocProject/Help/*.hhp 115 | DocProject/Help/Html2 116 | DocProject/Help/html 117 | 118 | # Click-Once directory 119 | publish/ 120 | 121 | # Publish Web Output 122 | *.[Pp]ublish.xml 123 | *.azurePubxml 124 | 125 | # NuGet Packages Directory 126 | packages/ 127 | ## TODO: If the tool you use requires repositories.config uncomment the next line 128 | #!packages/repositories.config 129 | 130 | # Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets 131 | # This line needs to be after the ignore of the build folder (and the packages folder if the line above has been uncommented) 132 | !packages/build/ 133 | 134 | # Windows Azure Build Output 135 | csx/ 136 | *.build.csdef 137 | 138 | # Windows Store app package directory 139 | AppPackages/ 140 | 141 | # Others 142 | sql/ 143 | *.Cache 144 | ClientBin/ 145 | [Ss]tyle[Cc]op.* 146 | ~$* 147 | *~ 148 | *.dbmdl 149 | *.dbproj.schemaview 150 | *.pfx 151 | *.publishsettings 152 | node_modules/ 153 | 154 | # RIA/Silverlight projects 155 | Generated_Code/ 156 | 157 | # Backup & report files from converting an old project file to a newer 158 | # Visual Studio version. Backup files are not needed, because we have git ;-) 159 | _UpgradeReport_Files/ 160 | Backup*/ 161 | UpgradeLog*.XML 162 | UpgradeLog*.htm 163 | 164 | # SQL Server files 165 | *.mdf 166 | *.ldf 167 | 168 | # Business Intelligence projects 169 | *.rdl.data 170 | *.bim.layout 171 | *.bim_*.settings 172 | 173 | # Microsoft Fakes 174 | FakesAssemblies/ 175 | 176 | # Windows image file caches 177 | Thumbs.db 178 | ehthumbs.db 179 | 180 | # Folder config file 181 | Desktop.ini 182 | 183 | # Recycle Bin used on file shares 184 | $RECYCLE.BIN/ 185 | 186 | # Windows Installer files 187 | *.cab 188 | *.msi 189 | *.msm 190 | *.msp 191 | 192 | # kdiff backup files 193 | *.orig -------------------------------------------------------------------------------- /Changelog.md: -------------------------------------------------------------------------------- 1 | ##Version 0.1.0 2 | Initial release, see README.md for known issues and plans -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Michael Denny, Alessandro Alpi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | "to-do" items can be marked as: 3 | - TODO 4 | - HACK 5 | - BUG 6 | - ASK 7 | 8 | ##Download 9 | 10 | git clone https://github.com/engageitservices/SqlTodoExplorer.git 11 | 12 | ##Build 13 | 14 | In order to build the source, you need to install SQL Server Management Studio 2012 (also the Express version). 15 | 16 | ##Supported versions of SQL Server Management Studio 17 | - SSMS 2012 18 | - SSMS 2012 Express 19 | 20 | Support for other versions are in the [issues] section. 21 | 22 | 23 | ##Install 24 | 25 | - Build the solution SqlTodoExplorer.sln or download the [latest release](https://github.com/engageitservices/SqlTodoExplorer/releases) 26 | 27 | - Copy the `DamnTools.SqlTodoExplorer.dll` created in the bin folder to the following folder (create it if not exists): 28 | 29 | C:\Program Files\DamnTools\SqlTodoExplorer 30 | 31 | - Copy the `DamnTools.SqlTodoExplorer.AddIn` file (stored on \Source\SqlTodoExplorer folder) in the following folder (create it if not exists): 32 | 33 | C:\ProgramData\Microsoft\SQL Server Management Studio\\AddIns 34 | 35 | Microsoft SQL Server Management Studio 2012: 36 | C:\ProgramData\Microsoft\SQL Server Management Studio\11.0\AddIns 37 | 38 | - Edit the copy of the .AddIn file and change the path: 39 | 40 | C:\Program Files\DamnTools\SqlTodoExplorer\DamnTools.SqlTodoExplorer.dll 41 | 42 | After the setup, you will find a new menu command under the "Tools" menu of Sql Server Management Studio. 43 | 44 | ![SQL Todo Explorer menu command](https://raw.githubusercontent.com/wiki/DamnTools/SqlTodoExplorer/images/new_menu_command.png) 45 | 46 | The add-in view is a floating (by default) panel in your Sql Server Management Studio. You can dock the panel, pin and move it as any other panel within the IDE. 47 | 48 | ![SQL Todo Explorer panel](https://raw.githubusercontent.com/wiki/DamnTools/SqlTodoExplorer/images/panel.png) 49 | 50 | ##Debug 51 | 52 | In Visual Studio: 53 | 54 | - Open the project properties of "SqlTodoExplorer" project (ALT+ENTER) and fill in the "Debug->Start external application" option with the SQL Management Studio executable (Ssms.exe) full path: 55 | 56 | C:\Program Files (x86)\Microsoft SQL Server\\AddIns 57 | \Tools\Binn\ManagementStudio\Ssms.exe 58 | 59 | - Set the "Working directory" option to the Ssms.exe parent folder: 60 | 61 | C:\Program Files (x86)\Microsoft SQL Server\\AddIns 62 | \Tools\Binn\ManagementStudio\ 63 | 64 | - Close the project properties 65 | 66 | - Go to menu "Debug->Exceptions"... and uncheck the "Thrown" on "PInvokeStackImbalance" and "IvalidVariant" under "Managed Debugging Assistant" 67 | 68 | - Hit F5 69 | 70 | ##Features 71 | 72 | - Get the list of "to-do" items (TODO, HACK, BUG, ASK) of the selected connection in a specific user database 73 | - Filter by database 74 | - Filter by "to-do" item type 75 | - Choose from three layout results (Flat list, Grouped by "to-do" and Grouped by object type) 76 | - Drill/collapse the result when the layout is a treeview 77 | - When the layout is "Flat list", filter by as-you-type search directly in the comments 78 | - Double click an item in order to get the ALTER statement of the selected object in a new query window 79 | - Refresh the connection context 80 | - Export the results as CSV or XML file 81 | 82 | ##How to contribute? 83 | 84 | Your contributions to SqlTodoExplorer are very welcome. If you find a bug, please raise it as an issue. Even better fix it and send a pull request. If you like to help out with existing bugs and feature requests just check out the list of [issues] and grab and fix one. 85 | 86 | ###Contribution guideline 87 | This project uses [GitHub flow] for pull requests. 88 | So if you want to contribute, fork the repo, preferably create a local branch to avoid conflicts with other activities, fix an issue, run a build of the solution, and send a PR if all is green. 89 | 90 | 1. `master` must always be deployable. 91 | 2. **all changes** made through feature branches (pull-request + merge) 92 | 3. rebase to avoid/resolve conflicts; merge in to `master` 93 | 94 | Please rebase your code on top of the latest commits. 95 | Before working on your fork make sure you pull the latest so you work on top of the latest commits to avoid merge conflicts. 96 | Also before sending the pull request please rebase your code as there is a chance there have been new commits pushed after you pulled last. 97 | Please refer to [this guide](https://gist.github.com/jbenet/ee6c9ac48068889b0912#the-workflow) if you're new to git (thanks to [Juan Batiz-Benet](https://github.com/jbenet)). 98 | 99 | ##Authors 100 | 101 | - Michael Denny ([@dennymic]) 102 | - Alessandro Alpi ([@suxstellino]) 103 | 104 | __Contributors__ 105 | - See the [contributor] section 106 | 107 | ##License 108 | 109 | Engage It Services Sql Todo Explorer is released under the [MIT License]. 110 | 111 | ##Icon 112 | 113 | Icon and Logo created by [Daniela Malvisi] 114 | 115 | 116 | [Daniela Malvisi]: https://it.linkedin.com/pub/daniela-malvisi/61/859/275 117 | [MIT License]: https://github.com/engageitservices/SqlTodoExplorer/blob/master/LICENSE 118 | [contributor]: https://github.com/engageitservices/SqlTodoExplorer/graphs/contributors 119 | [@suxstellino]: https://twitter.com/suxstellino 120 | [@dennymic]: https://twitter.com/dennymic 121 | [issues]: https://github.com/engageitservices/SqlTodoExplorer/issues 122 | [GitHub flow]: http://scottchacon.com/2011/08/31/github-flow.html 123 | -------------------------------------------------------------------------------- /Source/.nuget/NuGet.Config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Source/SqlTodoExplorer.Tests.Client/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Source/SqlTodoExplorer.Tests.Client/FakePresentationDataService.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Diagnostics; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Xml.Serialization; 6 | using DamnTools.SqlTodoExplorer.Presentation.Model; 7 | using DamnTools.SqlTodoExplorer.Presentation.Model.Data; 8 | using DamnTools.SqlTodoExplorer.Services; 9 | using RoutineType = DamnTools.SqlTodoExplorer.Presentation.Model.Data.RoutineType; 10 | 11 | namespace DamnTools.SqlTodoExplorer.Tests.Client 12 | { 13 | public class FakePresentationDataService : IPresentationDataService 14 | { 15 | public List GetDataRecords(string databaseName, ITodoPattern todoPattern) 16 | { 17 | var dataRecords = new List 18 | { 19 | new RoutineDataRecord 20 | { 21 | Id = 1000, 22 | Schema = "HumanResources", 23 | Name = "proc_Employees_List", 24 | Definition = "--TODO: change here!", 25 | Tag = new TodoPattern 26 | { 27 | SearchPattern = @"(?<=\W|^)(?TODO)(.*)", 28 | Title = "TODO", 29 | Id = 1 30 | }, 31 | CommentIndex = 1, 32 | Type = RoutineType.StoredProcedure 33 | }, 34 | new RoutineDataRecord 35 | { 36 | Id = 2000, 37 | Schema = "HumanResources", 38 | Name = "proc_Employees_Get", 39 | Definition = "--BUG: and here!", 40 | Tag = new TodoPattern 41 | { 42 | SearchPattern = @"(?<=\W|^)(?BUG)(.*)", 43 | Title = "BUG", 44 | Id = 4 45 | }, 46 | CommentIndex = 2, 47 | Type = RoutineType.StoredProcedure 48 | }, 49 | new RoutineDataRecord 50 | { 51 | Id = 2000, 52 | Schema = "HumanResources", 53 | Name = "proc_Employees_Get", 54 | Definition = "--TODO: change the where condition with a better key.", 55 | Tag = new TodoPattern 56 | { 57 | SearchPattern = @"(?<=\W|^)(?TODO)(.*)", 58 | Title = "TODO", 59 | Id = 1 60 | }, 61 | CommentIndex = 3, 62 | Type = RoutineType.StoredProcedure 63 | }, 64 | new RoutineDataRecord 65 | { 66 | Id = 4000, 67 | Schema = "Sales", 68 | Name = "proc_Orders_Add", 69 | Definition = "--HACK: this is a workaround and it should be changed in next release.", 70 | Tag = new TodoPattern 71 | { 72 | SearchPattern = @"(?<=\W|^)(?HACK)(.*)", 73 | Title = "HACK", 74 | Id = 2 75 | }, 76 | CommentIndex = 4, 77 | Type = RoutineType.StoredProcedure 78 | }, 79 | new RoutineDataRecord 80 | { 81 | Id = 5000, 82 | Schema = "Sales", 83 | Name = "proc_OrderDetails_ListByOrderId", 84 | Definition = "--TODO: missing business logic.", 85 | Tag = new TodoPattern 86 | { 87 | SearchPattern = @"(?<=\W|^)(?TODO)(.*)", 88 | Title = "TODO", 89 | Id = 1 90 | }, 91 | CommentIndex = 5, 92 | Type = RoutineType.StoredProcedure 93 | }, 94 | new RoutineDataRecord 95 | { 96 | Id = 14000, 97 | Schema = "HumanResources", 98 | Name = "udf_Employees_Get", 99 | Definition = "--TODO: Add that information.", 100 | Tag = new TodoPattern 101 | { 102 | SearchPattern = @"(?<=\W|^)(?TODO)(.*)", 103 | Title = "TODO", 104 | Id = 1 105 | }, 106 | CommentIndex = 6, 107 | Type = RoutineType.Function 108 | }, 109 | new RoutineDataRecord 110 | { 111 | Id = 15000, 112 | Schema = "Sales", 113 | Name = "udf_Orders_Recompute", 114 | Definition = "--HACK: Added a hardcoded constraint. This should be improved.", 115 | Tag = new TodoPattern 116 | { 117 | SearchPattern = @"(?<=\W|^)(?HACK)(.*)", 118 | Title = "HACK", 119 | Id = 2 120 | }, 121 | CommentIndex = 7, 122 | Type = RoutineType.Function 123 | }, 124 | new RoutineDataRecord 125 | { 126 | Id = 15000, 127 | Schema = "Sales", 128 | Name = "udf_Orders_Recompute", 129 | Definition = "--ASK: What to do.. What to do?", 130 | Tag = new TodoPattern 131 | { 132 | SearchPattern = @"(?<=\W|^)(?ASK)(.*)", 133 | Title = "ASK", 134 | Id = 3 135 | }, 136 | CommentIndex = 8, 137 | Type = RoutineType.Function 138 | }, 139 | }; 140 | 141 | if (todoPattern != null) 142 | return dataRecords.Where(t => t.Tag.Id == todoPattern.Id).ToList(); 143 | 144 | return dataRecords; 145 | } 146 | 147 | public List GetDatabases() 148 | { 149 | var dataRecords = new List 150 | { 151 | new DatabaseDataRecord 152 | { 153 | Id = 1000, 154 | Name = "AdventureWorks" 155 | }, 156 | new DatabaseDataRecord 157 | { 158 | Id = 2000, 159 | Name = "tempDB" 160 | }, 161 | new DatabaseDataRecord 162 | { 163 | Id = 3000, 164 | Name = "Northwind" 165 | } 166 | }; 167 | 168 | return dataRecords; 169 | } 170 | 171 | public IReadOnlyList GetPatterns() 172 | { 173 | using (var reader = new StringReader(Services.Resources.DefaultTodoPatterns)) 174 | { 175 | var serializer = new XmlSerializer(typeof(List)); 176 | var todoPatterns = (List)serializer.Deserialize(reader); 177 | return todoPatterns; 178 | } 179 | } 180 | 181 | public void RefreshCurrentConnection() 182 | { 183 | Trace.TraceInformation("Current connection refreshed"); 184 | } 185 | 186 | public void NavigateTo(TodoItem todoItem) 187 | { 188 | Trace.TraceInformation("Navigate to {0}", todoItem); 189 | } 190 | } 191 | } -------------------------------------------------------------------------------- /Source/SqlTodoExplorer.Tests.Client/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Drawing; 3 | using System.Windows.Forms; 4 | using DamnTools.SqlTodoExplorer.Presentation; 5 | 6 | namespace DamnTools.SqlTodoExplorer.Tests.Client 7 | { 8 | static class Program 9 | { 10 | /// 11 | /// The main entry point for the application. 12 | /// 13 | [STAThread] 14 | static void Main() 15 | { 16 | Application.EnableVisualStyles(); 17 | Application.SetCompatibleTextRenderingDefault(false); 18 | 19 | var hostView = new Form(); 20 | 21 | var view = new SqlTodoExplorerView(); 22 | 23 | var presenter = new SqlTodoExplorerPresenter(view, new FakePresentationDataService()); 24 | presenter.Init(); 25 | 26 | hostView.SuspendLayout(); 27 | // 28 | // sqlTodoExplorerView1 29 | // 30 | view.Dock = DockStyle.Fill; 31 | view.Location = new Point(0, 0); 32 | view.Name = "SqlTodoExplorerView"; 33 | view.Size = new Size(818, 272); 34 | view.TabIndex = 0; 35 | // 36 | // HostView 37 | // 38 | hostView.AutoScaleDimensions = new SizeF(6F, 13F); 39 | hostView.AutoScaleMode = AutoScaleMode.Font; 40 | hostView.ClientSize = new Size(818, 272); 41 | hostView.Controls.Add(view); 42 | hostView.Name = "HostView"; 43 | hostView.Text = "SQL Todo Explorer by DamnTools"; 44 | hostView.ResumeLayout(false); 45 | 46 | Application.Run(hostView); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Source/SqlTodoExplorer.Tests.Client/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("DamnTools.SqlTodoExplorer.Tests.Client")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("DamnTools.SqlTodoExplorer.Tests.Client")] 13 | [assembly: AssemblyCopyright("Copyright © 2014")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("1a94b0e5-596a-4a80-8625-646997a53684")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Source/SqlTodoExplorer.Tests.Client/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.18449 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace DamnTools.SqlTodoExplorer.Tests.Client.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Source/SqlTodoExplorer.Tests.Client/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Source/SqlTodoExplorer.Tests.Client/SqlTodoExplorer.Tests.Client.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {A0A20973-3A6C-414A-A6D8-7D1548C724A5} 8 | WinExe 9 | Properties 10 | DamnTools.SqlTodoExplorer.Tests.Client 11 | DamnTools.SqlTodoExplorer.Tests.Client 12 | v4.5 13 | 512 14 | 15 | 16 | AnyCPU 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | false 25 | 26 | 27 | AnyCPU 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | SettingsSingleFileGenerator 53 | Settings.Designer.cs 54 | 55 | 56 | True 57 | Settings.settings 58 | True 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | {54c786e5-fd14-4036-92ae-e9f25b71534b} 67 | SqlTodoExplorer 68 | 69 | 70 | 71 | 78 | -------------------------------------------------------------------------------- /Source/SqlTodoExplorer.Tests/Presentation/When_navigate_todo_item.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using DamnTools.SqlTodoExplorer.Presentation; 3 | using DamnTools.SqlTodoExplorer.Presentation.Model; 4 | using DamnTools.SqlTodoExplorer.Services; 5 | using FluentAssertions; 6 | using Microsoft.VisualStudio.TestTools.UnitTesting; 7 | using Moq; 8 | 9 | namespace DamnTools.SqlTodoExplorer.Tests.Presentation 10 | { 11 | [TestClass] 12 | public class When_navigate_todo_item 13 | { 14 | [TestMethod] 15 | public void Should_script_the_object_as_alter() 16 | { 17 | var mockView = new Mock(); 18 | var mockDataService = new Mock(); 19 | var presenter = new SqlTodoExplorerPresenter(mockView.Object, mockDataService.Object); 20 | var todoItem = new TodoItem(); 21 | var metaData = new TreeNodeMetaData 22 | { 23 | TodoItem = todoItem 24 | }; 25 | 26 | mockView.Raise(x => x.NodeDoubleClicked += null, metaData); 27 | 28 | mockDataService.Verify(x => x.NavigateTo(It.Is(t => t.Equals(todoItem))), Times.Once); 29 | } 30 | 31 | [TestMethod] 32 | public void Passing_null_as_todo_item_Should_return_without_errors() 33 | { 34 | var mockView = new Mock(); 35 | var mockDataService = new Mock(); 36 | var presenter = new SqlTodoExplorerPresenter(mockView.Object, mockDataService.Object); 37 | var metaData = new TreeNodeMetaData 38 | { 39 | TodoItem = null 40 | }; 41 | 42 | mockView.Raise(x => x.NodeDoubleClicked += null, metaData); 43 | 44 | mockDataService.Verify(x => x.NavigateTo(It.IsAny()), Times.Never); 45 | } 46 | 47 | [TestMethod] 48 | public void Passing_null_as_argument_Should_return_without_errors() 49 | { 50 | var mockView = new Mock(); 51 | var mockDataService = new Mock(); 52 | var presenter = new SqlTodoExplorerPresenter(mockView.Object, mockDataService.Object); 53 | TreeNodeMetaData metaData = null; 54 | 55 | mockView.Raise(x => x.NodeDoubleClicked += null, metaData); 56 | 57 | mockDataService.Verify(x => x.NavigateTo(It.IsAny()), Times.Never); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Source/SqlTodoExplorer.Tests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("DamnTools.SqlTodoExplorer.Tests")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("DamnTools.SqlTodoExplorer.Tests")] 13 | [assembly: AssemblyCopyright("Copyright © 2014")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("4ddc5dfd-75ce-4b69-b90f-f0a4fb20c462")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Source/SqlTodoExplorer.Tests/Services/TodoPatternServiceTests.cs: -------------------------------------------------------------------------------- 1 | using DamnTools.SqlTodoExplorer.Services; 2 | using FluentAssertions; 3 | using Microsoft.VisualStudio.TestTools.UnitTesting; 4 | 5 | namespace DamnTools.SqlTodoExplorer.Tests.Services 6 | { 7 | [TestClass] 8 | public class TodoPatternServiceTests 9 | { 10 | [TestMethod] 11 | public void Should_be_able_to_get_the_list_of_todo_patterns() 12 | { 13 | var service = new TodoPatternService(); 14 | 15 | var todoPatterns = service.GetTodoPatterns(); 16 | 17 | todoPatterns.Should().NotBeNull().And.NotBeEmpty(); 18 | todoPatterns.Should().Contain(t => t.Title == "Todo" && t.Id == 1); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Source/SqlTodoExplorer.Tests/Services/When_read_RegexPattern_property_of_a_TodoPattern.cs: -------------------------------------------------------------------------------- 1 | using DamnTools.SqlTodoExplorer.Services; 2 | using FluentAssertions; 3 | using Microsoft.VisualStudio.TestTools.UnitTesting; 4 | 5 | namespace DamnTools.SqlTodoExplorer.Tests.Services 6 | { 7 | [TestClass] 8 | public class When_read_RegexPattern_property_of_a_TodoPattern 9 | { 10 | [TestMethod] 11 | public void Should_return_null_if_SearchPattern_is_null() 12 | { 13 | var todoPattern = new TodoPattern 14 | { 15 | SearchPattern = null 16 | }; 17 | 18 | var regex = todoPattern.PatternRegex; 19 | 20 | regex.Should().BeNull(); 21 | } 22 | 23 | [TestMethod] 24 | public void Should_return_null_if_SearchPattern_is_empty() 25 | { 26 | var todoPattern = new TodoPattern 27 | { 28 | SearchPattern = string.Empty 29 | }; 30 | 31 | var regex = todoPattern.PatternRegex; 32 | 33 | regex.Should().BeNull(); 34 | } 35 | 36 | [TestMethod] 37 | public void Should_return_the_regex_of_a_valid_SearchPattern() 38 | { 39 | var searchPattern = @"Valid_SearchPattern\d+"; 40 | var todoPattern = new TodoPattern 41 | { 42 | SearchPattern = searchPattern 43 | }; 44 | 45 | var regex = todoPattern.PatternRegex; 46 | 47 | regex.Should().NotBeNull(); 48 | regex.ToString().Should().Be(searchPattern); 49 | } 50 | 51 | [TestMethod] 52 | public void Should_return_the_same_regex_reference_when_reading_twice() 53 | { 54 | var searchPattern = @"Valid_SearchPattern\d+"; 55 | var todoPattern = new TodoPattern 56 | { 57 | SearchPattern = searchPattern 58 | }; 59 | 60 | var firstRead = todoPattern.PatternRegex; 61 | var secondRead = todoPattern.PatternRegex; 62 | 63 | firstRead.Should().BeSameAs(secondRead); 64 | } 65 | 66 | [TestMethod] 67 | public void Should_return_the_updated_regex_when_changing_the_SearchPattern() 68 | { 69 | var todoPattern = new TodoPattern(); 70 | 71 | var originalSearchPattern = @"Original_SearchPattern\d+"; 72 | todoPattern.SearchPattern = originalSearchPattern; 73 | var originalRegex = todoPattern.PatternRegex; 74 | 75 | // change the search pattern 76 | var newSearchPattern = @"Changed_SearchPattern\d+"; 77 | todoPattern.SearchPattern = newSearchPattern; 78 | var newRegex = todoPattern.PatternRegex; 79 | 80 | originalRegex.Should().NotBeNull(); 81 | originalRegex.ToString().Should().Be(originalSearchPattern); 82 | 83 | newRegex.Should().NotBeNull(); 84 | newRegex.ToString().Should().Be(newSearchPattern); 85 | 86 | originalRegex.Should().NotBeSameAs(newRegex); 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /Source/SqlTodoExplorer.Tests/SqlTodoExplorer.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | {F9C092A3-8E9C-4E90-878D-C41DE66A1A3A} 7 | Library 8 | Properties 9 | DamnTools.SqlTodoExplorer.Tests 10 | DamnTools.SqlTodoExplorer.Tests 11 | v4.5 12 | 512 13 | {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 14 | 10.0 15 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 16 | $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages 17 | False 18 | UnitTest 19 | SAK 20 | SAK 21 | SAK 22 | SAK 23 | 24 | 25 | true 26 | full 27 | false 28 | bin\Debug\ 29 | DEBUG;TRACE 30 | prompt 31 | 4 32 | 33 | 34 | pdbonly 35 | true 36 | bin\Release\ 37 | TRACE 38 | prompt 39 | 4 40 | 41 | 42 | 43 | ..\packages\FluentAssertions.2.2.0.0\lib\net45\FluentAssertions.dll 44 | 45 | 46 | ..\packages\Moq.4.2.1402.2112\lib\net40\Moq.dll 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | {54c786e5-fd14-4036-92ae-e9f25b71534b} 73 | SqlTodoExplorer 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | False 85 | 86 | 87 | False 88 | 89 | 90 | False 91 | 92 | 93 | False 94 | 95 | 96 | 97 | 98 | 99 | 100 | 107 | -------------------------------------------------------------------------------- /Source/SqlTodoExplorer.Tests/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Source/SqlTodoExplorer.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SqlTodoExplorer", "SqlTodoExplorer\SqlTodoExplorer.csproj", "{54C786E5-FD14-4036-92AE-E9F25B71534B}" 5 | EndProject 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SqlTodoExplorer.Tests", "SqlTodoExplorer.Tests\SqlTodoExplorer.Tests.csproj", "{F9C092A3-8E9C-4E90-878D-C41DE66A1A3A}" 7 | EndProject 8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{DF9C7073-755A-43C0-B197-82516AF3FCB4}" 9 | ProjectSection(SolutionItems) = preProject 10 | .nuget\NuGet.Config = .nuget\NuGet.Config 11 | EndProjectSection 12 | EndProject 13 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SqlTodoExplorer.Tests.Client", "SqlTodoExplorer.Tests.Client\SqlTodoExplorer.Tests.Client.csproj", "{A0A20973-3A6C-414A-A6D8-7D1548C724A5}" 14 | EndProject 15 | Global 16 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 17 | Debug|Any CPU = Debug|Any CPU 18 | Release|Any CPU = Release|Any CPU 19 | EndGlobalSection 20 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 21 | {54C786E5-FD14-4036-92AE-E9F25B71534B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 22 | {54C786E5-FD14-4036-92AE-E9F25B71534B}.Debug|Any CPU.Build.0 = Debug|Any CPU 23 | {54C786E5-FD14-4036-92AE-E9F25B71534B}.Release|Any CPU.ActiveCfg = Release|Any CPU 24 | {54C786E5-FD14-4036-92AE-E9F25B71534B}.Release|Any CPU.Build.0 = Release|Any CPU 25 | {F9C092A3-8E9C-4E90-878D-C41DE66A1A3A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 26 | {F9C092A3-8E9C-4E90-878D-C41DE66A1A3A}.Debug|Any CPU.Build.0 = Debug|Any CPU 27 | {F9C092A3-8E9C-4E90-878D-C41DE66A1A3A}.Release|Any CPU.ActiveCfg = Release|Any CPU 28 | {F9C092A3-8E9C-4E90-878D-C41DE66A1A3A}.Release|Any CPU.Build.0 = Release|Any CPU 29 | {A0A20973-3A6C-414A-A6D8-7D1548C724A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 30 | {A0A20973-3A6C-414A-A6D8-7D1548C724A5}.Debug|Any CPU.Build.0 = Debug|Any CPU 31 | {A0A20973-3A6C-414A-A6D8-7D1548C724A5}.Release|Any CPU.ActiveCfg = Release|Any CPU 32 | {A0A20973-3A6C-414A-A6D8-7D1548C724A5}.Release|Any CPU.Build.0 = Release|Any CPU 33 | EndGlobalSection 34 | GlobalSection(SolutionProperties) = preSolution 35 | HideSolutionNode = FALSE 36 | EndGlobalSection 37 | EndGlobal 38 | -------------------------------------------------------------------------------- /Source/SqlTodoExplorer/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | 3 | // 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | // 8 | [assembly: AssemblyTitle("SqlTodoExplorer")] 9 | [assembly: AssemblyDescription("SQL Todo Explorer is a SQL Server Management Studio add-in. It helps to navigate the list of 'to-do' items within your databases.")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("DamnTools")] 12 | [assembly: AssemblyProduct("SqlTodoExplorer")] 13 | [assembly: AssemblyCopyright("Copyright 2014")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // 18 | // Version information for an assembly consists of the following four values: 19 | // 20 | // Major Version 21 | // Minor Version 22 | // Revision 23 | // Build Number 24 | // 25 | // You can specify all the value or you can default the Revision and Build Numbers 26 | // by using the '*' as shown below: 27 | 28 | [assembly: AssemblyVersion("0.1.0")] 29 | 30 | // 31 | // In order to sign your assembly you must specify a key to use. Refer to the 32 | // Microsoft .NET Framework documentation for more information on assembly signing. 33 | // 34 | // Use the attributes below to control which key is used for signing. 35 | // 36 | // Notes: 37 | // (*) If no key is specified - the assembly cannot be signed. 38 | // (*) KeyName refers to a key that has been installed in the Crypto Service 39 | // Provider (CSP) on your machine. 40 | // (*) If the key file and a key name attributes are both specified, the 41 | // following processing occurs: 42 | // (1) If the KeyName can be found in the CSP - that key is used. 43 | // (2) If the KeyName does not exist and the KeyFile does exist, the key 44 | // in the file is installed into the CSP and used. 45 | // (*) Delay Signing is an advanced option - see the Microsoft .NET Framework 46 | // documentation for more information on this. 47 | // 48 | [assembly: AssemblyDelaySign(false)] 49 | [assembly: AssemblyKeyFile("")] 50 | [assembly: AssemblyKeyName("")] 51 | -------------------------------------------------------------------------------- /Source/SqlTodoExplorer/Connect.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using DamnTools.SqlTodoExplorer.Presentation; 4 | using DamnTools.SqlTodoExplorer.Services; 5 | using EnvDTE; 6 | using EnvDTE80; 7 | using Extensibility; 8 | using Microsoft.SqlServer.Management.UI.VSIntegration; 9 | using Microsoft.VisualStudio.CommandBars; 10 | 11 | namespace DamnTools.SqlTodoExplorer 12 | { 13 | /// The object for implementing an Add-in. 14 | /// 15 | public class Connect : IDTExtensibility2, IDTCommandTarget 16 | { 17 | private AddIn _addInInstance; 18 | private DTE2 _applicationObject; 19 | 20 | /// 21 | /// Implements the OnConnection method of the IDTExtensibility2 interface. Receives notification that the Add-in 22 | /// is being loaded. 23 | /// 24 | /// Root object of the host application. 25 | /// Describes how the Add-in is being loaded. 26 | /// Object representing this Add-in. 27 | /// 28 | public void OnConnection(object application, ext_ConnectMode connectMode, object addInInst, ref Array custom) 29 | { 30 | _applicationObject = (DTE2)application; 31 | _addInInstance = (AddIn)addInInst; 32 | if (connectMode == ext_ConnectMode.ext_cm_Startup) 33 | { 34 | object[] contextGUIDS = { }; 35 | var commands = (Commands2)_applicationObject.Commands; 36 | string toolsMenuName = "Tools"; 37 | 38 | //Place the command on the tools menu. 39 | //Find the MenuBar command bar, which is the top-level command bar holding all the main menu items: 40 | CommandBar menuBarCommandBar = ((CommandBars)_applicationObject.CommandBars)["MenuBar"]; 41 | 42 | //Find the Tools command bar on the MenuBar command bar: 43 | CommandBarControl toolsControl = menuBarCommandBar.Controls[toolsMenuName]; 44 | var toolsPopup = (CommandBarPopup)toolsControl; 45 | 46 | //This try/catch block can be duplicated if you wish to add multiple commands to be handled by your Add-in, 47 | // just make sure you also update the QueryStatus/Exec method to include the new command names. 48 | try 49 | { 50 | //Add a command to the Commands collection: 51 | Command command = commands.AddNamedCommand2(_addInInstance, "OpenTodoExplorerGui", "SQL Todo Explorer", "Opens the to-do explorer", false, 1, ref contextGUIDS, (int)vsCommandStatus.vsCommandStatusSupported + (int)vsCommandStatus.vsCommandStatusEnabled, (int)vsCommandStyle.vsCommandStylePictAndText, vsCommandControlType.vsCommandControlTypeButton); 52 | 53 | //Add a control for the command to the tools menu: 54 | if ((command != null) && (toolsPopup != null)) 55 | { 56 | command.AddControl(toolsPopup.CommandBar, 1); 57 | } 58 | } 59 | catch (ArgumentException) 60 | { 61 | //If we are here, then the exception is probably because a command with that name 62 | // already exists. If so there is no need to recreate the command and we can 63 | // safely ignore the exception. 64 | } 65 | } 66 | } 67 | 68 | /// 69 | /// Implements the OnDisconnection method of the IDTExtensibility2 interface. Receives notification that the 70 | /// Add-in is being unloaded. 71 | /// 72 | /// Describes how the Add-in is being unloaded. 73 | /// Array of parameters that are host application specific. 74 | /// 75 | public void OnDisconnection(ext_DisconnectMode disconnectMode, ref Array custom) 76 | { 77 | var commands = (Commands2)_applicationObject.Commands; 78 | try 79 | { 80 | Command addinCommand = commands.Item("DamnTools.SqlTodoExplorer.Connect.OpenTodoExplorerGui"); 81 | addinCommand.Delete(); 82 | } 83 | catch (ArgumentException e) 84 | { 85 | Debug.Print("Error deleting commands on disconnection: {0}", e); 86 | } 87 | } 88 | 89 | /// 90 | /// Implements the QueryStatus method of the IDTCommandTarget interface. This is called when the command's 91 | /// availability is updated 92 | /// 93 | /// The name of the command to determine state for. 94 | /// Text that is needed for the command. 95 | /// The state of the command in the user interface. 96 | /// Text requested by the neededText parameter. 97 | /// 98 | public void QueryStatus(string commandName, vsCommandStatusTextWanted neededText, ref vsCommandStatus status, ref object commandText) 99 | { 100 | if (neededText == vsCommandStatusTextWanted.vsCommandStatusTextWantedNone) 101 | { 102 | if (commandName == "DamnTools.SqlTodoExplorer.Connect.OpenTodoExplorerGui") 103 | { 104 | status = vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled; 105 | } 106 | } 107 | } 108 | 109 | /// Implements the Exec method of the IDTCommandTarget interface. This is called when the command is invoked. 110 | /// The name of the command to execute. 111 | /// Describes how the command should be run. 112 | /// Parameters passed from the caller to the command handler. 113 | /// Parameters passed from the command handler to the caller. 114 | /// Informs the caller if the command was handled or not. 115 | /// 116 | public void Exec(string commandName, vsCommandExecOption executeOption, ref object varIn, ref object varOut, ref bool handled) 117 | { 118 | handled = false; 119 | if (executeOption == vsCommandExecOption.vsCommandExecOptionDoDefault) 120 | { 121 | if (commandName == "DamnTools.SqlTodoExplorer.Connect.OpenTodoExplorerGui") 122 | { 123 | var dte = ServiceCache.ExtensibilityModel; 124 | var windowsManager = new WindowsManager(dte); 125 | var title = SqlTodoExplorer.Properties.Resources.ViewTitle; 126 | windowsManager.ShowWindow(_addInInstance, title, width: 728, height: 300); 127 | 128 | handled = true; 129 | } 130 | } 131 | } 132 | 133 | /// 134 | /// Implements the OnAddInsUpdate method of the IDTExtensibility2 interface. Receives notification when the 135 | /// collection of Add-ins has changed. 136 | /// 137 | /// Array of parameters that are host application specific. 138 | /// 139 | public void OnAddInsUpdate(ref Array custom) 140 | { 141 | } 142 | 143 | /// 144 | /// Implements the OnStartupComplete method of the IDTExtensibility2 interface. Receives notification that the 145 | /// host application has completed loading. 146 | /// 147 | /// Array of parameters that are host application specific. 148 | /// 149 | public void OnStartupComplete(ref Array custom) 150 | { 151 | } 152 | 153 | /// 154 | /// Implements the OnBeginShutdown method of the IDTExtensibility2 interface. Receives notification that the host 155 | /// application is being unloaded. 156 | /// 157 | /// Array of parameters that are host application specific. 158 | /// 159 | public void OnBeginShutdown(ref Array custom) 160 | { 161 | } 162 | } 163 | } -------------------------------------------------------------------------------- /Source/SqlTodoExplorer/DamnTools.SqlTodoExplorer.AddIn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EngageLabsIt/SqlTodoExplorer/73729e5b12868947cd83fba3b9af4580b5e76f7b/Source/SqlTodoExplorer/DamnTools.SqlTodoExplorer.AddIn -------------------------------------------------------------------------------- /Source/SqlTodoExplorer/Presentation/Helpers/ToolStripRender.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Forms; 2 | 3 | namespace DamnTools.SqlTodoExplorer.Presentation.Helpers 4 | { 5 | public class ToolStripRender : ToolStripSystemRenderer 6 | { 7 | protected override void OnRenderToolStripBorder(ToolStripRenderEventArgs e) 8 | { 9 | // prevents the defaul render 10 | //base.OnRenderToolStripBorder(e); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Source/SqlTodoExplorer/Presentation/ISqlTodoExplorerView.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using DamnTools.SqlTodoExplorer.Presentation.Model; 5 | using DamnTools.SqlTodoExplorer.Presentation.Model.Data; 6 | using DamnTools.SqlTodoExplorer.Services; 7 | 8 | namespace DamnTools.SqlTodoExplorer.Presentation 9 | { 10 | public interface ISqlTodoExplorerView 11 | { 12 | event Action RefreshClicked; 13 | 14 | event Action DatabaseSelected; 15 | 16 | event Action CommentTypeFilterSelected; 17 | 18 | event Action GroupByItemSelected; 19 | 20 | event Action SaveFileDialogTxtConfirmed; 21 | 22 | event Action SaveFileDialogXmlConfirmed; 23 | 24 | event Action SearchTextChanged; 25 | 26 | event Action NodeDoubleClicked; 27 | 28 | string SearchWatermark { get; set; } 29 | 30 | string SearchText { get; set; } 31 | 32 | DatabaseName Database { get; set; } 33 | 34 | GroupByItem GroupBy { get; set; } 35 | 36 | FilterItem FilterType { get; set; } 37 | 38 | void LoadGroupByItems(IEnumerable groupByItems); 39 | 40 | void LoadCommentTypeFilters(IEnumerable filters); 41 | 42 | void LoadDatabases(IEnumerable databases); 43 | 44 | void LoadResultsByObjectType(IEnumerable routines); 45 | 46 | void LoadResultsByCommentType(IEnumerable routines); 47 | 48 | void LoadResultsInFlatList(IEnumerable routines); 49 | 50 | void ClearSelectedCommentTypeFilter(); 51 | 52 | void ClearSelectedGroupBy(); 53 | 54 | void ClearSelectedDatabase(); 55 | 56 | /// 57 | /// removes the row selection on grid at load or change text 58 | /// 59 | void ClearSelectedResults(); 60 | 61 | /// 62 | /// Shows the treeview instead of datagridview (hierarchycal list) 63 | /// 64 | void EnableTreeview(); 65 | 66 | /// 67 | /// Enables the treeview based controls 68 | /// 69 | void EnableTreeviewBasedItems(); 70 | 71 | /// 72 | /// Shows the datagridview instead of treeview (flat list) 73 | /// 74 | void EnableDatagridview(); 75 | 76 | /// 77 | /// Disables the treeview based controls 78 | /// 79 | void DisableTreeviewBasedItems(); 80 | 81 | void ApplyFilter(string filter); 82 | 83 | void FocusResultsView(); 84 | 85 | Stream OpenFileTxt(); 86 | 87 | Stream OpenFileXml(); 88 | 89 | /// 90 | /// Returns a DatabaseName object by a given id 91 | /// 92 | DatabaseName GetDabaseNameFromId(int id); 93 | 94 | /// 95 | /// Sets a DatabaseName object to the database list based control 96 | /// 97 | void SetDabaseName(DatabaseName database); 98 | } 99 | } -------------------------------------------------------------------------------- /Source/SqlTodoExplorer/Presentation/Model/Data/DatabaseDataRecord.cs: -------------------------------------------------------------------------------- 1 | namespace DamnTools.SqlTodoExplorer.Presentation.Model.Data 2 | { 3 | public class DatabaseDataRecord 4 | { 5 | public int Id { get; set; } 6 | public string Name { get; set; } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Source/SqlTodoExplorer/Presentation/Model/Data/RoutineDataRecord.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using DamnTools.SqlTodoExplorer.Services; 3 | 4 | namespace DamnTools.SqlTodoExplorer.Presentation.Model.Data 5 | { 6 | public class RoutineDataRecord 7 | { 8 | public int Id { get; set; } 9 | public string Schema { get; set; } 10 | public string Name { get; set; } 11 | public RoutineType Type { get; set; } 12 | public ITodoPattern Tag { get; set; } 13 | public string Definition { get; set; } 14 | public int CommentIndex { get; set; } 15 | public TodoItem TodoItem { get; set; } 16 | public string FullName 17 | { 18 | get 19 | { 20 | return String.Format("{0}.{1}", Schema, Name); 21 | } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Source/SqlTodoExplorer/Presentation/Model/Data/RoutineType.cs: -------------------------------------------------------------------------------- 1 | namespace DamnTools.SqlTodoExplorer.Presentation.Model.Data 2 | { 3 | public enum RoutineType 4 | { 5 | Unknown = 0, 6 | StoredProcedure = 1, 7 | Function = 2 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Source/SqlTodoExplorer/Presentation/Model/DatabaseName.cs: -------------------------------------------------------------------------------- 1 | namespace DamnTools.SqlTodoExplorer.Presentation.Model 2 | { 3 | public class DatabaseName 4 | { 5 | public int Id { get; set; } 6 | public string Name { get; set; } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Source/SqlTodoExplorer/Presentation/Model/FilterItemType.cs: -------------------------------------------------------------------------------- 1 | using DamnTools.SqlTodoExplorer.Services; 2 | 3 | namespace DamnTools.SqlTodoExplorer.Presentation.Model 4 | { 5 | public class FilterItem 6 | { 7 | public ITodoPattern Id { get; set; } 8 | public string Description { get; set; } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Source/SqlTodoExplorer/Presentation/Model/GroupByItemType.cs: -------------------------------------------------------------------------------- 1 | namespace DamnTools.SqlTodoExplorer.Presentation.Model 2 | { 3 | public class GroupByItem 4 | { 5 | public GroupByItemType Id { get; set; } 6 | public string Description { get; set; } 7 | } 8 | 9 | public enum GroupByItemType 10 | { 11 | Unknown = 0, 12 | ObjectType = 1, 13 | CommentType = 2, 14 | Flat = 3 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Source/SqlTodoExplorer/Presentation/Model/IPresentationDataService.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using DamnTools.SqlTodoExplorer.Presentation.Model.Data; 3 | using DamnTools.SqlTodoExplorer.Services; 4 | 5 | namespace DamnTools.SqlTodoExplorer.Presentation.Model 6 | { 7 | public interface IPresentationDataService 8 | { 9 | /// 10 | /// Gets data from the source provider. 11 | /// 12 | List GetDataRecords(string databaseName, ITodoPattern searchPattern); 13 | 14 | /// 15 | /// Gets database list from the source provider. 16 | /// 17 | List GetDatabases(); 18 | 19 | /// 20 | /// Gets all the search patterns. 21 | /// 22 | IReadOnlyList GetPatterns(); 23 | 24 | /// 25 | /// Refresh the connection selecting the current instance 26 | /// where the user is working on. It first checks the active 27 | /// script/document, if not document is active, it fallsback 28 | /// to the object explorer and get the selected instance. 29 | /// 30 | void RefreshCurrentConnection(); 31 | 32 | /// 33 | /// Script the object as alter, and move the caret where 34 | /// the to-do has been found. 35 | /// 36 | void NavigateTo(TodoItem todoItem); 37 | } 38 | } -------------------------------------------------------------------------------- /Source/SqlTodoExplorer/Presentation/Model/NodeType.cs: -------------------------------------------------------------------------------- 1 | namespace DamnTools.SqlTodoExplorer.Presentation.Model 2 | { 3 | public enum NodeType 4 | { 5 | Unknown = 0, 6 | RootStoredProcedure = 1, 7 | RootFunction = 2, 8 | Schema = 3, 9 | StoredProcedure = 4, 10 | Function = 5, 11 | Comment = 6 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Source/SqlTodoExplorer/Presentation/Model/PresentationDataService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using DamnTools.SqlTodoExplorer.Presentation.Model.Data; 7 | using DamnTools.SqlTodoExplorer.Services; 8 | using RoutineType = DamnTools.SqlTodoExplorer.Presentation.Model.Data.RoutineType; 9 | 10 | namespace DamnTools.SqlTodoExplorer.Presentation.Model 11 | { 12 | public class PresentationDataService : IPresentationDataService 13 | { 14 | private ITodoExplorerManager _todoExplorerManager; 15 | 16 | public PresentationDataService() 17 | { 18 | _todoExplorerManager = TodoExplorer.CreateFromCurrentConnection(); 19 | } 20 | 21 | /// 22 | /// Gets data from the source provider 23 | /// 24 | public List GetDataRecords(string databaseName, ITodoPattern searchPattern) 25 | { 26 | var todoItems = _todoExplorerManager.GetTodoItems(databaseName, searchPattern); 27 | var dataRecords = todoItems.Select(t => new RoutineDataRecord 28 | { 29 | Id = t.RoutineId, 30 | Schema = t.RoutineSchema, 31 | Name = t.RoutineName, 32 | Definition = t.Text, 33 | Tag = t.Pattern, 34 | Type = GetDataRoutineType(t.RoutineType), 35 | CommentIndex = t.TextIndex, 36 | TodoItem = t 37 | }).ToList(); 38 | return dataRecords; 39 | } 40 | 41 | /// 42 | /// Gets database list from the source provider 43 | /// 44 | public List GetDatabases() 45 | { 46 | var databases = _todoExplorerManager.GetDatabases(); 47 | var dataRecords = databases.Select(t => new DatabaseDataRecord 48 | { 49 | Id = t.GetHashCode(), // HACK: the API requires only the database name. You can compare strings instead of the id if you're using in the view for filtering or so on. 50 | Name = t 51 | }).ToList(); 52 | return dataRecords; 53 | } 54 | 55 | /// 56 | /// Gets all the search patterns. 57 | /// 58 | public IReadOnlyList GetPatterns() 59 | { 60 | return _todoExplorerManager.GetTodoPatterns(); 61 | } 62 | 63 | /// 64 | /// Refresh the connection selecting the current instance 65 | /// where the user is working on. It first checks the active 66 | /// script/document, if not document is active, it fallsback 67 | /// to the object explorer and get the selected instance. 68 | /// 69 | public void RefreshCurrentConnection() 70 | { 71 | _todoExplorerManager = TodoExplorer.CreateFromCurrentConnection(); 72 | } 73 | 74 | /// 75 | /// Script the object as alter, and move the caret where 76 | /// the to-do has been found. 77 | /// 78 | public void NavigateTo(TodoItem todoItem) 79 | { 80 | _todoExplorerManager.NavigateTo(todoItem); 81 | } 82 | 83 | public RoutineType GetDataRoutineType(Services.RoutineType type) 84 | { 85 | switch (type) 86 | { 87 | case Services.RoutineType.StoredProcedure: 88 | return RoutineType.StoredProcedure; 89 | case Services.RoutineType.Function: 90 | return RoutineType.Function; 91 | default: 92 | return RoutineType.Unknown; 93 | } 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /Source/SqlTodoExplorer/Presentation/Model/TreeNodeMetaData.cs: -------------------------------------------------------------------------------- 1 | using DamnTools.SqlTodoExplorer.Services; 2 | 3 | namespace DamnTools.SqlTodoExplorer.Presentation.Model 4 | { 5 | public class TreeNodeMetaData 6 | { 7 | public NodeType NodeType { get; set; } 8 | 9 | public TodoItem TodoItem { get; set; } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Source/SqlTodoExplorer/Presentation/SqlTodoExplorerPresenter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Xml.Linq; 8 | using DamnTools.SqlTodoExplorer.Presentation.Model; 9 | using DamnTools.SqlTodoExplorer.Presentation.Model.Data; 10 | using DamnTools.SqlTodoExplorer.Services; 11 | using Resources = DamnTools.SqlTodoExplorer.Properties.Resources; 12 | 13 | namespace DamnTools.SqlTodoExplorer.Presentation 14 | { 15 | public class SqlTodoExplorerPresenter 16 | { 17 | private readonly ISqlTodoExplorerView _view; 18 | private readonly IPresentationDataService _dataService; 19 | 20 | public List DataRecords { get; private set; } 21 | 22 | public SqlTodoExplorerPresenter(ISqlTodoExplorerView view, IPresentationDataService dataService) 23 | { 24 | _view = view; 25 | _dataService = dataService; 26 | 27 | _view.RefreshClicked += ViewOnRefreshClicked; 28 | _view.DatabaseSelected += ViewOnDatabaseSelected; 29 | _view.CommentTypeFilterSelected += ViewOnCommentTypeFilterSelected; 30 | _view.GroupByItemSelected += ViewOnGroupByItemSelected; 31 | _view.SaveFileDialogTxtConfirmed += ViewOnSaveFileDialogTxtConfirmed; 32 | _view.SaveFileDialogXmlConfirmed += ViewOnSaveFileDialogXmlConfirmed; 33 | _view.SearchTextChanged += ViewOnSearchTextChanged; 34 | _view.NodeDoubleClicked += ViewOnNodeDoubleClicked; 35 | } 36 | 37 | public void ViewOnRefreshClicked() 38 | { 39 | // gets the selected database id (prior to refhresh) 40 | var databaseId = _view.Database.Id; 41 | 42 | // updates/rebinds controls 43 | RefreshControlsAndRebindData(); 44 | BindDatabases(); 45 | 46 | // selects the last database selected 47 | _view.SetDabaseName(_view.GetDabaseNameFromId(databaseId)); 48 | } 49 | 50 | public void ViewOnDatabaseSelected() 51 | { 52 | RefreshControlsAndRebindData(); 53 | } 54 | 55 | /// 56 | /// Changes the treeview results based on FilterItemType 57 | /// 58 | public void ViewOnCommentTypeFilterSelected() 59 | { 60 | if (_view.FilterType != null) 61 | { 62 | var selectedFilterOption = _view.FilterType.Id; 63 | var comboBoxGroupByItem = _view.GroupBy; 64 | 65 | if (comboBoxGroupByItem == null) 66 | { 67 | _view.EnableTreeview(); 68 | _view.EnableTreeviewBasedItems(); 69 | BindTreeviewData(GroupByItemType.Unknown, selectedFilterOption); 70 | } 71 | else 72 | { 73 | var selectedGroupByOption = comboBoxGroupByItem.Id; 74 | 75 | if (selectedGroupByOption != GroupByItemType.Flat) 76 | { 77 | _view.EnableTreeview(); 78 | _view.EnableTreeviewBasedItems(); 79 | BindTreeviewData(selectedGroupByOption, selectedFilterOption); 80 | } 81 | else 82 | { 83 | _view.EnableDatagridview(); 84 | _view.DisableTreeviewBasedItems(); 85 | BindFlatListData(selectedFilterOption); 86 | } 87 | } 88 | 89 | _view.FocusResultsView(); 90 | } 91 | } 92 | 93 | /// 94 | /// Changes the result view layout (grouped by object types or comment type) 95 | /// 96 | public void ViewOnGroupByItemSelected() 97 | { 98 | _view.SearchText = string.Empty; 99 | 100 | if (_view.GroupBy != null) 101 | { 102 | var selectedGroupByOption = _view.GroupBy.Id; 103 | var comboBoxFilterItem = _view.FilterType; 104 | 105 | if (comboBoxFilterItem == null) 106 | { 107 | if (selectedGroupByOption != GroupByItemType.Flat) 108 | { 109 | _view.EnableTreeview(); 110 | _view.EnableTreeviewBasedItems(); 111 | BindTreeviewData(selectedGroupByOption, null); 112 | } 113 | else 114 | { 115 | _view.EnableDatagridview(); 116 | _view.DisableTreeviewBasedItems(); 117 | BindFlatListData(null); 118 | } 119 | } 120 | else 121 | { 122 | var selectedFilterOption = ((FilterItem)comboBoxFilterItem).Id; 123 | if (selectedGroupByOption != GroupByItemType.Flat) 124 | { 125 | _view.EnableTreeview(); 126 | _view.EnableTreeviewBasedItems(); 127 | BindTreeviewData(selectedGroupByOption, selectedFilterOption); 128 | } 129 | else 130 | { 131 | _view.EnableDatagridview(); 132 | _view.DisableTreeviewBasedItems(); 133 | BindFlatListData(selectedFilterOption); 134 | } 135 | } 136 | 137 | _view.FocusResultsView(); 138 | } 139 | } 140 | 141 | /// 142 | /// Export to TXT file (csv format) 143 | /// 144 | public void ViewOnSaveFileDialogTxtConfirmed() 145 | { 146 | using (var file = new StreamWriter(_view.OpenFileTxt())) 147 | { 148 | try 149 | { 150 | var sb = new StringBuilder(); 151 | 152 | // headers 153 | sb.AppendFormat("{0}, ", Resources.ColumnObjectId); 154 | sb.AppendFormat("{0}, ", Resources.ColumnSchema); 155 | sb.AppendFormat("{0}, ", Resources.ColumnName); 156 | sb.AppendFormat("{0}, ", Resources.ColumnFullName); 157 | sb.AppendFormat("{0}, ", Resources.ColumnType); 158 | sb.AppendFormat("{0}, ", Resources.ColumnCommentType); 159 | sb.AppendFormat("{0}{1}", Resources.ColumnDefinition, Environment.NewLine); 160 | 161 | foreach (var record in this.DataRecords) 162 | { 163 | if (!String.IsNullOrEmpty(_view.SearchText)) 164 | { 165 | if (record.Definition.Contains(_view.SearchText)) 166 | { 167 | sb.AppendFormat("{0}, ", record.Id); 168 | sb.AppendFormat("{0}, ", record.Schema); 169 | sb.AppendFormat("{0}, ", record.Name); 170 | sb.AppendFormat("{0}, ", record.FullName); 171 | sb.AppendFormat("{0}, ", record.Type); 172 | sb.AppendFormat("{0}, ", record.Tag); 173 | sb.AppendFormat("{0}{1}", record.Definition, Environment.NewLine); 174 | } 175 | } 176 | else 177 | { 178 | sb.AppendFormat("{0}, ", record.Id); 179 | sb.AppendFormat("{0}, ", record.Schema); 180 | sb.AppendFormat("{0}, ", record.Name); 181 | sb.AppendFormat("{0}, ", record.FullName); 182 | sb.AppendFormat("{0}, ", record.Type); 183 | sb.AppendFormat("{0}, ", record.Tag); 184 | sb.AppendFormat("{0}{1}", record.Definition, Environment.NewLine); 185 | } 186 | } 187 | 188 | file.WriteLine(sb.ToString()); 189 | file.Close(); 190 | 191 | Trace.TraceInformation("File saved successfully"); 192 | } 193 | catch (Exception ex) 194 | { 195 | Trace.TraceError(ex.ToString()); 196 | file.Close(); 197 | } 198 | } 199 | } 200 | 201 | /// 202 | /// Export to XML file 203 | /// 204 | public void ViewOnSaveFileDialogXmlConfirmed() 205 | { 206 | using (var file = new StreamWriter(_view.OpenFileXml())) 207 | { 208 | try 209 | { 210 | var xml = new XElement("Comments", this.DataRecords 211 | .Where(x => x.Definition.Contains(_view.SearchText)) 212 | .Select(x => new XElement("Comment", 213 | new XAttribute("ObjectId", x.Id), 214 | new XAttribute("Schema", x.Schema), 215 | new XAttribute("ObjectName", x.Name), 216 | new XAttribute("FullName", x.FullName), 217 | new XAttribute("Type", x.Type), 218 | new XAttribute("Tag", x.Tag), 219 | new XAttribute("Definition", x.Definition)))); 220 | 221 | xml.Save(file); 222 | file.Close(); 223 | 224 | Trace.TraceInformation("File saved successfully"); 225 | } 226 | catch (Exception ex) 227 | { 228 | Trace.TraceError(ex.ToString()); 229 | file.Close(); 230 | } 231 | } 232 | } 233 | 234 | /// 235 | /// Filters with the as you type search 236 | /// 237 | public void ViewOnSearchTextChanged() 238 | { 239 | var selectedGroupByType = _view.GroupBy.Id; 240 | switch (selectedGroupByType) 241 | { 242 | case GroupByItemType.Flat: 243 | _view.ApplyFilter(_view.SearchText); 244 | break; 245 | case GroupByItemType.CommentType: 246 | case GroupByItemType.ObjectType: 247 | break; 248 | } 249 | 250 | _view.ClearSelectedResults(); 251 | } 252 | 253 | /// 254 | /// Script the object as alter, and move the caret where 255 | /// the to-do has been found. 256 | /// 257 | public void ViewOnNodeDoubleClicked(TreeNodeMetaData treeNodeMetaData) 258 | { 259 | if (treeNodeMetaData == null) return; 260 | if (treeNodeMetaData.TodoItem == null) return; 261 | 262 | _dataService.NavigateTo(treeNodeMetaData.TodoItem); 263 | } 264 | 265 | /// 266 | /// Inits the controls 267 | /// 268 | public void Init() 269 | { 270 | _view.SearchWatermark = Resources.SearchWatermark; 271 | 272 | // toolbox data load 273 | BindToolboxData(); 274 | 275 | _view.ClearSelectedCommentTypeFilter(); 276 | _view.ClearSelectedGroupBy(); 277 | 278 | // gets all data 279 | _view.EnableTreeview(); 280 | BindTreeviewData(GroupByItemType.Unknown, null); 281 | } 282 | 283 | /// 284 | /// Loads toolstrip control data 285 | /// 286 | public void BindToolboxData() 287 | { 288 | BindGroupByObjectTypes(); 289 | BindFilterItemTypes(); 290 | BindDatabases(); 291 | } 292 | 293 | /// 294 | /// Binds the group by type list 295 | /// 296 | public void BindGroupByObjectTypes() 297 | { 298 | var groupByItemTypeObjectType = new GroupByItem { Id = GroupByItemType.ObjectType, Description = Resources.GroupByItemTypeObjectType }; 299 | var groupByItemTypeCommentType = new GroupByItem { Id = GroupByItemType.CommentType, Description = Resources.GroupByItemTypeCommentType }; 300 | var groupByItemTypeFlat = new GroupByItem { Id = GroupByItemType.Flat, Description = Resources.GroupByItemTypeFlat }; 301 | 302 | _view.LoadGroupByItems(new[] { groupByItemTypeObjectType, groupByItemTypeCommentType, groupByItemTypeFlat }); 303 | } 304 | 305 | /// 306 | /// Binds the filter type list 307 | /// 308 | public void BindFilterItemTypes() 309 | { 310 | var patterns = _dataService.GetPatterns(); 311 | 312 | var patternList = new List(); 313 | 314 | patternList.Add(new FilterItem { Id = null, Description = Resources.FilterItemTypeAll }); 315 | patternList.AddRange(patterns.Select(todoPattern => new FilterItem {Id = todoPattern, Description = todoPattern.Title})); 316 | 317 | _view.LoadCommentTypeFilters(patternList); 318 | } 319 | 320 | /// 321 | /// Binds the database list given by the data source 322 | /// 323 | public void BindDatabases() 324 | { 325 | List data = _dataService.GetDatabases(); 326 | 327 | var database = data.Select(t => new DatabaseName { Id = t.Id, Name = t.Name }).ToList(); 328 | 329 | _view.LoadDatabases(database); 330 | 331 | _view.ClearSelectedDatabase(); 332 | } 333 | 334 | /// 335 | /// Binds the treeview from data source 336 | /// 337 | /// Layout stlye 338 | /// ITodoPattern filter 339 | public void BindTreeviewData(GroupByItemType groupByItemType, ITodoPattern todoPattern) 340 | { 341 | var data = GetRoutineDataRecords(_view.Database.Name, todoPattern); 342 | 343 | switch (groupByItemType) 344 | { 345 | case GroupByItemType.Unknown: 346 | case GroupByItemType.ObjectType: 347 | _view.LoadResultsByObjectType(data); 348 | break; 349 | case GroupByItemType.CommentType: 350 | _view.LoadResultsByCommentType(data); 351 | break; 352 | default: 353 | _view.LoadResultsByObjectType(data); 354 | break; 355 | } 356 | } 357 | 358 | /// 359 | /// Groups the results by a flat list 360 | /// 361 | /// ITodoPattern filter 362 | public void BindFlatListData(ITodoPattern todoPattern) 363 | { 364 | var data = GetRoutineDataRecords(_view.Database.Name, todoPattern); 365 | 366 | _view.LoadResultsInFlatList(data); 367 | 368 | _view.ApplyFilter(_view.SearchText); 369 | 370 | _view.ClearSelectedResults(); 371 | } 372 | 373 | /// 374 | /// Updates the status of the results controls 375 | /// 376 | public void RefreshControlsAndRebindData() 377 | { 378 | var filterSelectedItem = _view.FilterType; 379 | var groupBySelectedItem = _view.GroupBy; 380 | 381 | if (filterSelectedItem == null || groupBySelectedItem == null) 382 | return; 383 | 384 | var selectedGroupByOption = groupBySelectedItem.Id; 385 | var selectedFilterOption = filterSelectedItem.Id; 386 | 387 | if (selectedGroupByOption != GroupByItemType.Flat) 388 | { 389 | _view.EnableTreeview(); 390 | _view.EnableTreeviewBasedItems(); 391 | BindTreeviewData(selectedGroupByOption, selectedFilterOption); 392 | } 393 | else 394 | { 395 | _view.EnableDatagridview(); 396 | _view.DisableTreeviewBasedItems(); 397 | BindFlatListData(selectedFilterOption); 398 | } 399 | } 400 | 401 | public List GetRoutineDataRecords(string database, ITodoPattern searchPattern) 402 | { 403 | this.DataRecords = _dataService.GetDataRecords(database, searchPattern); 404 | return this.DataRecords; 405 | } 406 | } 407 | } -------------------------------------------------------------------------------- /Source/SqlTodoExplorer/Presentation/SqlTodoExplorerView.en.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | Expand all 122 | 123 | 124 | Collapse all 125 | 126 | 127 | Previous item 128 | 129 | 130 | Next item 131 | 132 | 133 | 134 | 56, 22 135 | 136 | 137 | Export 138 | 139 | 140 | 141 | Ctrl+T 142 | 143 | 144 | 157, 22 145 | 146 | 147 | as Text 148 | 149 | 150 | Ctrl+M 151 | 152 | 153 | 157, 22 154 | 155 | 156 | as XML 157 | 158 | -------------------------------------------------------------------------------- /Source/SqlTodoExplorer/Presentation/SqlTodoExplorerView.it-IT.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 122 | 123 | iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO 124 | wwAADsMBx2+oZAAAAgNJREFUOE+lkutLk2EYxvePhJaHShFBUTEPiCieQOmDiEZgrEbpYGiCQxkqA80I 125 | RUkUEZ0YRMS+DDI70MkTmzJnDc8iU8QT2mAEItnle90wHwTDyBduXnie5/rd133Q4ZKfAJqHFs9E08A8 126 | zD1emDpmYXjqRlnTFIrMk8iuGkNaxWekGEaQrHecBfw+/vPXODw6hj9whN2fh/Bt/8LSRgA3cxr/DeBZ 127 | 9kvmTNMoHGNbIrYN+3Aj23IxgJkpds0doP3VstgmsNexhutZ9QrAms8T0zYzU5xXM46kcjsmvfvoeL2i 128 | AeoUgA07T8yaaZuZKab1rzN74jgys1YB2O2gmBZzH49LODXrrJlnzEzxe9cOLH1ziMioVgCOiuIFX0CE 129 | Q+/WYf+yieiCFrRp9tkwxnP7Kt5MbKGm6wfC000KwDlTXNLgEvHMkh+Db32o7fYivtQm1l9+3IBOp5P7 130 | yjYPwlKNCsAluWudxgvtknb5t9oWcL/VLU2Mvd2JFq3uqs7vAtE/ceNayiMF4KiYMSjmY2O7B4Ua+NaD 131 | YQGEJumRbvyG1IcfBHI12aAAXM8R57aIWTNrLLY4tfNPiCvpR1SeVeu6WWzHFD6THSDwFMDdpmUG62NJ 132 | PKM4Or9ZxBxb8H8l7g5CEu8pAOfM3WanSeeS8CFHxW4zM2umbWamOCShXAH+/wNOANABIDUxWnDPAAAA 133 | AElFTkSuQmCC 134 | 135 | 136 | 137 | Magenta 138 | 139 | 140 | toolStripButton1 141 | 142 | 143 | Espandi tutto 144 | 145 | 146 | 147 | iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO 148 | wwAADsMBx2+oZAAAAgNJREFUOE+lkutLk2EYxvePhJaHShFBUTEPiCieQOmDiEZgrEbpYGiCQxkqA80I 149 | RUkUEZ0YRMS+DDI70MkTmzJnDc8iU8QT2mAEItnle90wHwTDyBduXnie5/rd133Q4ZKfAJqHFs9E08A8 150 | zD1emDpmYXjqRlnTFIrMk8iuGkNaxWekGEaQrHecBfw+/vPXODw6hj9whN2fh/Bt/8LSRgA3cxr/DeBZ 151 | 9kvmTNMoHGNbIrYN+3Aj23IxgJkpds0doP3VstgmsNexhutZ9QrAms8T0zYzU5xXM46kcjsmvfvoeL2i 152 | AeoUgA07T8yaaZuZKab1rzN74jgys1YB2O2gmBZzH49LODXrrJlnzEzxe9cOLH1ziMioVgCOiuIFX0CE 153 | Q+/WYf+yieiCFrRp9tkwxnP7Kt5MbKGm6wfC000KwDlTXNLgEvHMkh+Db32o7fYivtQm1l9+3IBOp5P7 154 | yjYPwlKNCsAluWudxgvtknb5t9oWcL/VLU2Mvd2JFq3uqs7vAtE/ceNayiMF4KiYMSjmY2O7B4Ua+NaD 155 | YQGEJumRbvyG1IcfBHI12aAAXM8R57aIWTNrLLY4tfNPiCvpR1SeVeu6WWzHFD6THSDwFMDdpmUG62NJ 156 | PKM4Or9ZxBxb8H8l7g5CEu8pAOfM3WanSeeS8CFHxW4zM2umbWamOCShXAH+/wNOANABIDUxWnDPAAAA 157 | AElFTkSuQmCC 158 | 159 | 160 | 161 | Magenta 162 | 163 | 164 | toolStripButton1 165 | 166 | 167 | Chiudi tutto 168 | 169 | 170 | 171 | iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO 172 | wwAADsMBx2+oZAAAAgNJREFUOE+lkutLk2EYxvePhJaHShFBUTEPiCieQOmDiEZgrEbpYGiCQxkqA80I 173 | RUkUEZ0YRMS+DDI70MkTmzJnDc8iU8QT2mAEItnle90wHwTDyBduXnie5/rd133Q4ZKfAJqHFs9E08A8 174 | zD1emDpmYXjqRlnTFIrMk8iuGkNaxWekGEaQrHecBfw+/vPXODw6hj9whN2fh/Bt/8LSRgA3cxr/DeBZ 175 | 9kvmTNMoHGNbIrYN+3Aj23IxgJkpds0doP3VstgmsNexhutZ9QrAms8T0zYzU5xXM46kcjsmvfvoeL2i 176 | AeoUgA07T8yaaZuZKab1rzN74jgys1YB2O2gmBZzH49LODXrrJlnzEzxe9cOLH1ziMioVgCOiuIFX0CE 177 | Q+/WYf+yieiCFrRp9tkwxnP7Kt5MbKGm6wfC000KwDlTXNLgEvHMkh+Db32o7fYivtQm1l9+3IBOp5P7 178 | yjYPwlKNCsAluWudxgvtknb5t9oWcL/VLU2Mvd2JFq3uqs7vAtE/ceNayiMF4KiYMSjmY2O7B4Ua+NaD 179 | YQGEJumRbvyG1IcfBHI12aAAXM8R57aIWTNrLLY4tfNPiCvpR1SeVeu6WWzHFD6THSDwFMDdpmUG62NJ 180 | PKM4Or9ZxBxb8H8l7g5CEu8pAOfM3WanSeeS8CFHxW4zM2umbWamOCShXAH+/wNOANABIDUxWnDPAAAA 181 | AElFTkSuQmCC 182 | 183 | 184 | 185 | Magenta 186 | 187 | 188 | Elemento precedente 189 | 190 | 191 | 192 | iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO 193 | wwAADsMBx2+oZAAAAgNJREFUOE+lkutLk2EYxvePhJaHShFBUTEPiCieQOmDiEZgrEbpYGiCQxkqA80I 194 | RUkUEZ0YRMS+DDI70MkTmzJnDc8iU8QT2mAEItnle90wHwTDyBduXnie5/rd133Q4ZKfAJqHFs9E08A8 195 | zD1emDpmYXjqRlnTFIrMk8iuGkNaxWekGEaQrHecBfw+/vPXODw6hj9whN2fh/Bt/8LSRgA3cxr/DeBZ 196 | 9kvmTNMoHGNbIrYN+3Aj23IxgJkpds0doP3VstgmsNexhutZ9QrAms8T0zYzU5xXM46kcjsmvfvoeL2i 197 | AeoUgA07T8yaaZuZKab1rzN74jgys1YB2O2gmBZzH49LODXrrJlnzEzxe9cOLH1ziMioVgCOiuIFX0CE 198 | Q+/WYf+yieiCFrRp9tkwxnP7Kt5MbKGm6wfC000KwDlTXNLgEvHMkh+Db32o7fYivtQm1l9+3IBOp5P7 199 | yjYPwlKNCsAluWudxgvtknb5t9oWcL/VLU2Mvd2JFq3uqs7vAtE/ceNayiMF4KiYMSjmY2O7B4Ua+NaD 200 | YQGEJumRbvyG1IcfBHI12aAAXM8R57aIWTNrLLY4tfNPiCvpR1SeVeu6WWzHFD6THSDwFMDdpmUG62NJ 201 | PKM4Or9ZxBxb8H8l7g5CEu8pAOfM3WanSeeS8CFHxW4zM2umbWamOCShXAH+/wNOANABIDUxWnDPAAAA 202 | AElFTkSuQmCC 203 | 204 | 205 | 206 | Magenta 207 | 208 | 209 | Elemento successivo 210 | 211 | 212 | 213 | Ctrl+T 214 | 215 | 216 | 177, 22 217 | 218 | 219 | come Testo 220 | 221 | 222 | Ctrl+M 223 | 224 | 225 | 177, 22 226 | 227 | 228 | come XML 229 | 230 | 231 | 232 | iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO 233 | wwAADsMBx2+oZAAAAgNJREFUOE+lkutLk2EYxvePhJaHShFBUTEPiCieQOmDiEZgrEbpYGiCQxkqA80I 234 | RUkUEZ0YRMS+DDI70MkTmzJnDc8iU8QT2mAEItnle90wHwTDyBduXnie5/rd133Q4ZKfAJqHFs9E08A8 235 | zD1emDpmYXjqRlnTFIrMk8iuGkNaxWekGEaQrHecBfw+/vPXODw6hj9whN2fh/Bt/8LSRgA3cxr/DeBZ 236 | 9kvmTNMoHGNbIrYN+3Aj23IxgJkpds0doP3VstgmsNexhutZ9QrAms8T0zYzU5xXM46kcjsmvfvoeL2i 237 | AeoUgA07T8yaaZuZKab1rzN74jgys1YB2O2gmBZzH49LODXrrJlnzEzxe9cOLH1ziMioVgCOiuIFX0CE 238 | Q+/WYf+yieiCFrRp9tkwxnP7Kt5MbKGm6wfC000KwDlTXNLgEvHMkh+Db32o7fYivtQm1l9+3IBOp5P7 239 | yjYPwlKNCsAluWudxgvtknb5t9oWcL/VLU2Mvd2JFq3uqs7vAtE/ceNayiMF4KiYMSjmY2O7B4Ua+NaD 240 | YQGEJumRbvyG1IcfBHI12aAAXM8R57aIWTNrLLY4tfNPiCvpR1SeVeu6WWzHFD6THSDwFMDdpmUG62NJ 241 | PKM4Or9ZxBxb8H8l7g5CEu8pAOfM3WanSeeS8CFHxW4zM2umbWamOCShXAH+/wNOANABIDUxWnDPAAAA 242 | AElFTkSuQmCC 243 | 244 | 245 | 246 | Magenta 247 | 248 | 249 | 62, 22 250 | 251 | 252 | Esporta 253 | 254 | 255 | Esporta 256 | 257 | -------------------------------------------------------------------------------- /Source/SqlTodoExplorer/Presentation/WartermarkTextBox.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | using System.Windows.Forms; 4 | 5 | namespace DamnTools.SqlTodoExplorer.Presentation 6 | { 7 | public static class TextBoxWatermarkExtensionMethod 8 | { 9 | private const uint ECM_FIRST = 0x1500; 10 | private const uint EM_SETCUEBANNER = ECM_FIRST + 1; 11 | 12 | [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)] 13 | private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, uint wParam, [MarshalAs(UnmanagedType.LPWStr)] string lParam); 14 | 15 | public static void SetWatermark(this TextBox textBox, string watermarkText) 16 | { 17 | SendMessage(textBox.Handle, EM_SETCUEBANNER, 0, watermarkText); 18 | } 19 | 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Source/SqlTodoExplorer/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.34011 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace DamnTools.SqlTodoExplorer.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DamnTools.SqlTodoExplorer.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | 63 | /// 64 | /// Looks up a localized resource of type System.Drawing.Bitmap. 65 | /// 66 | internal static System.Drawing.Bitmap arrow_Sync_16xLG { 67 | get { 68 | object obj = ResourceManager.GetObject("arrow_Sync_16xLG", resourceCulture); 69 | return ((System.Drawing.Bitmap)(obj)); 70 | } 71 | } 72 | 73 | /// 74 | /// Looks up a localized resource of type System.Drawing.Bitmap. 75 | /// 76 | internal static System.Drawing.Bitmap Collapse { 77 | get { 78 | object obj = ResourceManager.GetObject("Collapse", resourceCulture); 79 | return ((System.Drawing.Bitmap)(obj)); 80 | } 81 | } 82 | 83 | /// 84 | /// Looks up a localized string similar to Tag. 85 | /// 86 | internal static string ColumnCommentType { 87 | get { 88 | return ResourceManager.GetString("ColumnCommentType", resourceCulture); 89 | } 90 | } 91 | 92 | /// 93 | /// Looks up a localized string similar to Comment details. 94 | /// 95 | internal static string ColumnDefinition { 96 | get { 97 | return ResourceManager.GetString("ColumnDefinition", resourceCulture); 98 | } 99 | } 100 | 101 | /// 102 | /// Looks up a localized string similar to Full name. 103 | /// 104 | internal static string ColumnFullName { 105 | get { 106 | return ResourceManager.GetString("ColumnFullName", resourceCulture); 107 | } 108 | } 109 | 110 | /// 111 | /// Looks up a localized string similar to Name. 112 | /// 113 | internal static string ColumnName { 114 | get { 115 | return ResourceManager.GetString("ColumnName", resourceCulture); 116 | } 117 | } 118 | 119 | /// 120 | /// Looks up a localized string similar to Object id. 121 | /// 122 | internal static string ColumnObjectId { 123 | get { 124 | return ResourceManager.GetString("ColumnObjectId", resourceCulture); 125 | } 126 | } 127 | 128 | /// 129 | /// Looks up a localized string similar to Schema. 130 | /// 131 | internal static string ColumnSchema { 132 | get { 133 | return ResourceManager.GetString("ColumnSchema", resourceCulture); 134 | } 135 | } 136 | 137 | /// 138 | /// Looks up a localized string similar to Routine type. 139 | /// 140 | internal static string ColumnType { 141 | get { 142 | return ResourceManager.GetString("ColumnType", resourceCulture); 143 | } 144 | } 145 | 146 | /// 147 | /// Looks up a localized resource of type System.Drawing.Bitmap. 148 | /// 149 | internal static System.Drawing.Bitmap Expand { 150 | get { 151 | object obj = ResourceManager.GetObject("Expand", resourceCulture); 152 | return ((System.Drawing.Bitmap)(obj)); 153 | } 154 | } 155 | 156 | /// 157 | /// Looks up a localized string similar to Text File|*.txt. 158 | /// 159 | internal static string FileTypeTxt { 160 | get { 161 | return ResourceManager.GetString("FileTypeTxt", resourceCulture); 162 | } 163 | } 164 | 165 | /// 166 | /// Looks up a localized string similar to XML File|*.xml. 167 | /// 168 | internal static string FileTypeXml { 169 | get { 170 | return ResourceManager.GetString("FileTypeXml", resourceCulture); 171 | } 172 | } 173 | 174 | /// 175 | /// Looks up a localized string similar to (all). 176 | /// 177 | internal static string FilterItemTypeAll { 178 | get { 179 | return ResourceManager.GetString("FilterItemTypeAll", resourceCulture); 180 | } 181 | } 182 | 183 | /// 184 | /// Looks up a localized string similar to (all). 185 | /// 186 | internal static string GroupByItemTypeAll { 187 | get { 188 | return ResourceManager.GetString("GroupByItemTypeAll", resourceCulture); 189 | } 190 | } 191 | 192 | /// 193 | /// Looks up a localized string similar to Tag. 194 | /// 195 | internal static string GroupByItemTypeCommentType { 196 | get { 197 | return ResourceManager.GetString("GroupByItemTypeCommentType", resourceCulture); 198 | } 199 | } 200 | 201 | /// 202 | /// Looks up a localized string similar to Flat. 203 | /// 204 | internal static string GroupByItemTypeFlat { 205 | get { 206 | return ResourceManager.GetString("GroupByItemTypeFlat", resourceCulture); 207 | } 208 | } 209 | 210 | /// 211 | /// Looks up a localized string similar to Object type. 212 | /// 213 | internal static string GroupByItemTypeObjectType { 214 | get { 215 | return ResourceManager.GetString("GroupByItemTypeObjectType", resourceCulture); 216 | } 217 | } 218 | 219 | /// 220 | /// Looks up a localized string similar to Schema {0}. 221 | /// 222 | internal static string NodeTextSchema { 223 | get { 224 | return ResourceManager.GetString("NodeTextSchema", resourceCulture); 225 | } 226 | } 227 | 228 | /// 229 | /// Looks up a localized resource of type System.Drawing.Bitmap. 230 | /// 231 | internal static System.Drawing.Bitmap PropertyIcon { 232 | get { 233 | object obj = ResourceManager.GetObject("PropertyIcon", resourceCulture); 234 | return ((System.Drawing.Bitmap)(obj)); 235 | } 236 | } 237 | 238 | /// 239 | /// Looks up a localized resource of type System.Drawing.Bitmap. 240 | /// 241 | internal static System.Drawing.Bitmap refresh_16xLG { 242 | get { 243 | object obj = ResourceManager.GetObject("refresh_16xLG", resourceCulture); 244 | return ((System.Drawing.Bitmap)(obj)); 245 | } 246 | } 247 | 248 | /// 249 | /// Looks up a localized string similar to Functions. 250 | /// 251 | internal static string RootNodeTextFunctions { 252 | get { 253 | return ResourceManager.GetString("RootNodeTextFunctions", resourceCulture); 254 | } 255 | } 256 | 257 | /// 258 | /// Looks up a localized string similar to Procedures. 259 | /// 260 | internal static string RootNodeTextProcedures { 261 | get { 262 | return ResourceManager.GetString("RootNodeTextProcedures", resourceCulture); 263 | } 264 | } 265 | 266 | /// 267 | /// Looks up a localized string similar to Type to search.... 268 | /// 269 | internal static string SearchWatermark { 270 | get { 271 | return ResourceManager.GetString("SearchWatermark", resourceCulture); 272 | } 273 | } 274 | 275 | /// 276 | /// Looks up a localized resource of type System.Drawing.Bitmap. 277 | /// 278 | internal static System.Drawing.Bitmap Textfile_818_16x { 279 | get { 280 | object obj = ResourceManager.GetObject("Textfile_818_16x", resourceCulture); 281 | return ((System.Drawing.Bitmap)(obj)); 282 | } 283 | } 284 | 285 | /// 286 | /// Looks up a localized string similar to Sql Todo Explorer. 287 | /// 288 | internal static string ViewTitle { 289 | get { 290 | return ResourceManager.GetString("ViewTitle", resourceCulture); 291 | } 292 | } 293 | 294 | /// 295 | /// Looks up a localized resource of type System.Drawing.Bitmap. 296 | /// 297 | internal static System.Drawing.Bitmap XMLFile_828_16x { 298 | get { 299 | object obj = ResourceManager.GetObject("XMLFile_828_16x", resourceCulture); 300 | return ((System.Drawing.Bitmap)(obj)); 301 | } 302 | } 303 | } 304 | } 305 | -------------------------------------------------------------------------------- /Source/SqlTodoExplorer/Properties/Resources.en.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 122 | ..\Resources\XMLFile_828_16x.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 123 | 124 | 125 | ..\Resources\Textfile_818_16x.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 126 | 127 | 128 | ..\Resources\collapse.gif;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 129 | 130 | 131 | ..\Resources\expand.gif;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 132 | 133 | 134 | ..\Resources\PropertyIcon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 135 | 136 | 137 | Type to search... 138 | 139 | 140 | Tag 141 | 142 | 143 | Object type 144 | 145 | 146 | Functions 147 | 148 | 149 | Procedures 150 | 151 | 152 | Schema {0} 153 | 154 | 155 | Flat 156 | 157 | 158 | Tag 159 | 160 | 161 | Comment details 162 | 163 | 164 | Full name 165 | 166 | 167 | Name 168 | 169 | 170 | Object id 171 | 172 | 173 | Schema 174 | 175 | 176 | Routine type 177 | 178 | 179 | Text File|*.txt 180 | 181 | 182 | XML File|*.xml 183 | 184 | 185 | (all) 186 | 187 | 188 | ..\Resources\refresh_16xLG.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 189 | 190 | 191 | ..\Resources\arrow_Sync_16xLG.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 192 | 193 | 194 | Sql Todo Explorer 195 | 196 | -------------------------------------------------------------------------------- /Source/SqlTodoExplorer/Properties/Resources.it.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 122 | ..\Resources\XMLFile_828_16x.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 123 | 124 | 125 | ..\Resources\Textfile_818_16x.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 126 | 127 | 128 | ..\Resources\collapse.gif;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 129 | 130 | 131 | ..\Resources\expand.gif;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 132 | 133 | 134 | ..\Resources\PropertyIcon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 135 | 136 | 137 | Cerca... 138 | 139 | 140 | (all) 141 | 142 | 143 | (all) 144 | 145 | 146 | Tag 147 | 148 | 149 | Tipo di oggetto 150 | 151 | 152 | Funzioni 153 | 154 | 155 | Procedure 156 | 157 | 158 | Schema {0} 159 | 160 | 161 | Lista semplice 162 | 163 | 164 | Tag 165 | 166 | 167 | Commento 168 | 169 | 170 | Nome completo 171 | 172 | 173 | Nome 174 | 175 | 176 | Object id 177 | 178 | 179 | Schema 180 | 181 | 182 | Tipo di routine 183 | 184 | 185 | File di testo|*.txt 186 | 187 | 188 | File XML|*.xml 189 | 190 | 191 | ..\Resources\refresh_16xLG.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 192 | 193 | 194 | ..\Resources\arrow_Sync_16xLG.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 195 | 196 | 197 | Sql Todo Explorer 198 | 199 | -------------------------------------------------------------------------------- /Source/SqlTodoExplorer/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | (all) 122 | 123 | 124 | Schema {0} 125 | 126 | 127 | 128 | ..\Resources\XMLFile_828_16x.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 129 | 130 | 131 | (all) 132 | 133 | 134 | Functions 135 | 136 | 137 | ..\Resources\expand.gif;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 138 | 139 | 140 | ..\Resources\PropertyIcon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 141 | 142 | 143 | ..\Resources\Textfile_818_16x.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 144 | 145 | 146 | ..\Resources\refresh_16xLG.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 147 | 148 | 149 | Tag 150 | 151 | 152 | ..\Resources\collapse.gif;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 153 | 154 | 155 | Procedures 156 | 157 | 158 | Type to search... 159 | 160 | 161 | Object type 162 | 163 | 164 | ..\Resources\arrow_Sync_16xLG.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 165 | 166 | 167 | Flat 168 | 169 | 170 | Tag 171 | 172 | 173 | Comment details 174 | 175 | 176 | Full name 177 | 178 | 179 | Name 180 | 181 | 182 | Object id 183 | 184 | 185 | Schema 186 | 187 | 188 | Routine type 189 | 190 | 191 | Text File|*.txt 192 | 193 | 194 | XML File|*.xml 195 | 196 | 197 | Sql Todo Explorer 198 | 199 | -------------------------------------------------------------------------------- /Source/SqlTodoExplorer/ReadMe.txt: -------------------------------------------------------------------------------- 1 | Instruction to run in debug: 2 | 3 | 1 - Copy the "DamnTools.SqlTodoExplorer.AddIn" file in the following folder: 4 | 5 | C:\ProgramData\Microsoft\SQL Server Management Studio\11.0\AddIns 6 | 7 | 2 - Edit the copy of the .AddIn file and change the path 8 | to point the debug dll "DamnTools.SqlTodoExplorer.dll" is, for example: 9 | 10 | C:\Users\UserAccount\Documents\Git\DamnTools\Source\SqlTodoExplorer\bin\DamnTools.SqlTodoExplorer.dll 11 | 12 | 3 - Open the project properties of "DamnTools.SqlTodoExplorer" project (ALT+ENTER) 13 | and edit the Debug->Start external application with the full path to the 14 | SQL Management Studio 2012 executable (Ssms.exe): 15 | 16 | C:\Program Files (x86)\Microsoft SQL Server\110\Tools\Binn\ManagementStudio\Ssms.exe 17 | 18 | and the Working directory corrisponding to the Ssms.exe parent folder: 19 | 20 | C:\Program Files (x86)\Microsoft SQL Server\110\Tools\Binn\ManagementStudio\ 21 | 22 | 4 - Go to Debug->Exceptions... and uncheck the Thrown on "PInvokeStackImbalance" and "IvalidVariant" under "Managed Debugging Assistant" 23 | 24 | 5 - Hit F5 -------------------------------------------------------------------------------- /Source/SqlTodoExplorer/Resources/1.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EngageLabsIt/SqlTodoExplorer/73729e5b12868947cd83fba3b9af4580b5e76f7b/Source/SqlTodoExplorer/Resources/1.bmp -------------------------------------------------------------------------------- /Source/SqlTodoExplorer/Resources/DefaultTodoPatterns.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 1 5 | Todo 6 | TODO)(.*)]]> 7 | 8 | 9 | 2 10 | Hack 11 | HACK)(.*)]]> 12 | 13 | 14 | 3 15 | Ask 16 | ASK)(.*)]]> 17 | 18 | 19 | 4 20 | Bug 21 | BUG)(.*)]]> 22 | 23 | -------------------------------------------------------------------------------- /Source/SqlTodoExplorer/Resources/PropertyIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EngageLabsIt/SqlTodoExplorer/73729e5b12868947cd83fba3b9af4580b5e76f7b/Source/SqlTodoExplorer/Resources/PropertyIcon.png -------------------------------------------------------------------------------- /Source/SqlTodoExplorer/Resources/Textfile_818_16x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EngageLabsIt/SqlTodoExplorer/73729e5b12868947cd83fba3b9af4580b5e76f7b/Source/SqlTodoExplorer/Resources/Textfile_818_16x.png -------------------------------------------------------------------------------- /Source/SqlTodoExplorer/Resources/XMLFile_828_16x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EngageLabsIt/SqlTodoExplorer/73729e5b12868947cd83fba3b9af4580b5e76f7b/Source/SqlTodoExplorer/Resources/XMLFile_828_16x.png -------------------------------------------------------------------------------- /Source/SqlTodoExplorer/Resources/arrow_Sync_16xLG.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EngageLabsIt/SqlTodoExplorer/73729e5b12868947cd83fba3b9af4580b5e76f7b/Source/SqlTodoExplorer/Resources/arrow_Sync_16xLG.png -------------------------------------------------------------------------------- /Source/SqlTodoExplorer/Resources/collapse.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EngageLabsIt/SqlTodoExplorer/73729e5b12868947cd83fba3b9af4580b5e76f7b/Source/SqlTodoExplorer/Resources/collapse.gif -------------------------------------------------------------------------------- /Source/SqlTodoExplorer/Resources/expand.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EngageLabsIt/SqlTodoExplorer/73729e5b12868947cd83fba3b9af4580b5e76f7b/Source/SqlTodoExplorer/Resources/expand.gif -------------------------------------------------------------------------------- /Source/SqlTodoExplorer/Resources/refresh_16xLG.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EngageLabsIt/SqlTodoExplorer/73729e5b12868947cd83fba3b9af4580b5e76f7b/Source/SqlTodoExplorer/Resources/refresh_16xLG.png -------------------------------------------------------------------------------- /Source/SqlTodoExplorer/Services/DbEnumTypeHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace DamnTools.SqlTodoExplorer.Services 4 | { 5 | public static class DbEnumTypeHelper 6 | { 7 | public static RoutineType GetRoutineType(string value) 8 | { 9 | if (value == null) throw new ArgumentNullException("value"); 10 | if (value.Equals("procedure", StringComparison.InvariantCultureIgnoreCase)) 11 | { 12 | return RoutineType.StoredProcedure; 13 | } 14 | if (value.Equals("function", StringComparison.InvariantCultureIgnoreCase)) 15 | { 16 | return RoutineType.Function; 17 | } 18 | throw new Exception(string.Format("The value '{0}' is not a valid RoutineType.", value)); 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /Source/SqlTodoExplorer/Services/IScriptService.cs: -------------------------------------------------------------------------------- 1 | namespace DamnTools.SqlTodoExplorer.Services 2 | { 3 | public interface IScriptService 4 | { 5 | void CreateNewScript(string content); 6 | } 7 | } -------------------------------------------------------------------------------- /Source/SqlTodoExplorer/Services/IServerConnectionService.cs: -------------------------------------------------------------------------------- 1 | namespace DamnTools.SqlTodoExplorer.Services 2 | { 3 | public interface IServerConnectionService 4 | { 5 | ServerConnectionInfo GetCurrentConnection(); 6 | } 7 | } -------------------------------------------------------------------------------- /Source/SqlTodoExplorer/Services/IServerGateway.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace DamnTools.SqlTodoExplorer.Services 4 | { 5 | public interface IServerGateway 6 | { 7 | IReadOnlyList GetDatabases(); 8 | 9 | IReadOnlyList GetRoutines(IEnumerable databases = null); 10 | 11 | Routine GetRoutine(string database, int routineId); 12 | } 13 | } -------------------------------------------------------------------------------- /Source/SqlTodoExplorer/Services/ITodoExplorerManager.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace DamnTools.SqlTodoExplorer.Services 4 | { 5 | public interface ITodoExplorerManager 6 | { 7 | IReadOnlyList GetDatabases(bool includeSystemDatabases = false); 8 | 9 | IReadOnlyList GetTodoItems(string database = null, ITodoPattern pattern = null, bool includeSystemDatabases = false); 10 | 11 | IReadOnlyList GetTodoItems(IEnumerable databases, IEnumerable patterns); 12 | 13 | IReadOnlyList GetTodoPatterns(); 14 | 15 | void NavigateTo(TodoItem todoItem); 16 | } 17 | } -------------------------------------------------------------------------------- /Source/SqlTodoExplorer/Services/ITodoPattern.cs: -------------------------------------------------------------------------------- 1 | namespace DamnTools.SqlTodoExplorer.Services 2 | { 3 | public interface ITodoPattern 4 | { 5 | int Id { get; } 6 | string Title { get; } 7 | string SearchPattern { get; } 8 | } 9 | } -------------------------------------------------------------------------------- /Source/SqlTodoExplorer/Services/ITodoPatternService.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace DamnTools.SqlTodoExplorer.Services 4 | { 5 | public interface ITodoPatternService 6 | { 7 | IReadOnlyList GetTodoPatterns(); 8 | } 9 | } -------------------------------------------------------------------------------- /Source/SqlTodoExplorer/Services/IWindowsManager.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Forms; 2 | using EnvDTE; 3 | using EnvDTE80; 4 | 5 | namespace DamnTools.SqlTodoExplorer.Services 6 | { 7 | public interface IWindowsManager 8 | { 9 | Window2 ShowWindow(AddIn addIn, string title, bool isFloating = true, int width = 450, int height = 450) where T : UserControl; 10 | } 11 | } -------------------------------------------------------------------------------- /Source/SqlTodoExplorer/Services/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.18449 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace DamnTools.SqlTodoExplorer.Services { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | public class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | public static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DamnTools.SqlTodoExplorer.Services.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | public static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | 63 | /// 64 | /// Looks up a localized resource of type System.Drawing.Bitmap. 65 | /// 66 | public static System.Drawing.Bitmap _1 { 67 | get { 68 | object obj = ResourceManager.GetObject("1", resourceCulture); 69 | return ((System.Drawing.Bitmap)(obj)); 70 | } 71 | } 72 | 73 | /// 74 | /// Looks up a localized string similar to master,model,msdb,tempdb. 75 | /// 76 | public static string Database_ExclusionList { 77 | get { 78 | return ResourceManager.GetString("Database_ExclusionList", resourceCulture); 79 | } 80 | } 81 | 82 | /// 83 | /// Looks up a localized string similar to <?xml version="1.0" encoding="utf-8" ?> 84 | ///<ArrayOfTodoPattern> 85 | /// <TodoPattern default="true"> 86 | /// <Title>Todo</Title> 87 | /// <SearchPattern><![CDATA[(?<=\W|^)(?<TAG>TODO)(.*)]]></SearchPattern> 88 | /// </TodoPattern> 89 | /// <TodoPattern> 90 | /// <Title>Hack</Title> 91 | /// <SearchPattern><![CDATA[(?<=\W|^)(?<TAG>HACK)(.*)]]></SearchPattern> 92 | /// </TodoPattern> 93 | /// <TodoPattern> 94 | /// <Title>Ask</Title> 95 | /// <SearchPattern><![CDATA[(?<=\W|^)(?<TAG>ASK)(.*)]]></SearchPattern> 96 | /// </TodoPattern> [rest of string was truncated]";. 97 | /// 98 | public static string DefaultTodoPatterns { 99 | get { 100 | return ResourceManager.GetString("DefaultTodoPatterns", resourceCulture); 101 | } 102 | } 103 | 104 | /// 105 | /// Looks up a localized string similar to ^\s*CREATE(?=\s*(?:PROCEDURE|PROC|FUNCTION|FUNC)). 106 | /// 107 | public static string ScriptAsAlter_ReplaceRegex { 108 | get { 109 | return ResourceManager.GetString("ScriptAsAlter_ReplaceRegex", resourceCulture); 110 | } 111 | } 112 | 113 | /// 114 | /// Looks up a localized string similar to USE [{0}] -- Database name 115 | ///SELECT 116 | /// ROUTINE_OBJECTID = SC.id 117 | /// , SR.ROUTINE_SCHEMA 118 | /// , SR.ROUTINE_NAME 119 | /// , ROUTINE_FULLNAME = SR.ROUTINE_SCHEMA + '.' + SR.ROUTINE_NAME 120 | /// , SR.ROUTINE_TYPE 121 | /// , SC.colid 122 | /// , ROUTINE_DEFINITION = SC.[text] 123 | ///FROM 124 | /// INFORMATION_SCHEMA.ROUTINES SR 125 | /// JOIN sys.syscomments SC ON SC.id = OBJECT_ID(ROUTINE_SCHEMA + '.' + ROUTINE_NAME) 126 | ///WHERE 127 | /// SC.id = {1} -- OBJECT_ID 128 | ///ORDER BY 129 | /// ROUTINE_OBJECTID, colid. 130 | /// 131 | public static string SQL_Routine { 132 | get { 133 | return ResourceManager.GetString("SQL_Routine", resourceCulture); 134 | } 135 | } 136 | 137 | /// 138 | /// Looks up a localized string similar to USE [{0}] -- Database name 139 | ///SELECT 140 | /// ROUTINE_OBJECTID = SC.id 141 | /// , SR.ROUTINE_SCHEMA 142 | /// , SR.ROUTINE_NAME 143 | /// , ROUTINE_FULLNAME = SR.ROUTINE_SCHEMA + '.' + SR.ROUTINE_NAME 144 | /// , SR.ROUTINE_TYPE 145 | /// , SC.colid 146 | /// , ROUTINE_DEFINITION = SC.[text] 147 | ///FROM 148 | /// INFORMATION_SCHEMA.ROUTINES SR 149 | /// JOIN sys.syscomments SC ON SC.id = OBJECT_ID(ROUTINE_SCHEMA + '.' + ROUTINE_NAME) 150 | ///ORDER BY 151 | /// ROUTINE_OBJECTID, colid. 152 | /// 153 | public static string SQL_Routines { 154 | get { 155 | return ResourceManager.GetString("SQL_Routines", resourceCulture); 156 | } 157 | } 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /Source/SqlTodoExplorer/Services/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | master,model,msdb,tempdb 122 | Comma separated list 123 | 124 | 125 | 126 | ..\resources\defaulttodopatterns.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 127 | 128 | 129 | USE [{0}] -- Database name 130 | SELECT 131 | ROUTINE_OBJECTID = SC.id 132 | , SR.ROUTINE_SCHEMA 133 | , SR.ROUTINE_NAME 134 | , ROUTINE_FULLNAME = SR.ROUTINE_SCHEMA + '.' + SR.ROUTINE_NAME 135 | , SR.ROUTINE_TYPE 136 | , SC.colid 137 | , ROUTINE_DEFINITION = SC.[text] 138 | FROM 139 | INFORMATION_SCHEMA.ROUTINES SR 140 | JOIN sys.syscomments SC ON SC.id = OBJECT_ID(ROUTINE_SCHEMA + '.' + ROUTINE_NAME) 141 | ORDER BY 142 | ROUTINE_OBJECTID, colid 143 | Query to retrieve all the routines of a database 144 | 145 | 146 | USE [{0}] -- Database name 147 | SELECT 148 | ROUTINE_OBJECTID = SC.id 149 | , SR.ROUTINE_SCHEMA 150 | , SR.ROUTINE_NAME 151 | , ROUTINE_FULLNAME = SR.ROUTINE_SCHEMA + '.' + SR.ROUTINE_NAME 152 | , SR.ROUTINE_TYPE 153 | , SC.colid 154 | , ROUTINE_DEFINITION = SC.[text] 155 | FROM 156 | INFORMATION_SCHEMA.ROUTINES SR 157 | JOIN sys.syscomments SC ON SC.id = OBJECT_ID(ROUTINE_SCHEMA + '.' + ROUTINE_NAME) 158 | WHERE 159 | SC.id = {1} -- OBJECT_ID 160 | ORDER BY 161 | ROUTINE_OBJECTID, colid 162 | Query to retrieve one routine of a database by its OBJECT_ID 163 | 164 | 165 | ..\resources\1.bmp;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 166 | 167 | 168 | ^\s*CREATE(?=\s*(?:PROCEDURE|PROC|FUNCTION|FUNC)) 169 | Regular expression to replace the CREATE PROCEDURE statement with ALTER PROCEDURE 170 | 171 | -------------------------------------------------------------------------------- /Source/SqlTodoExplorer/Services/Routine.cs: -------------------------------------------------------------------------------- 1 | namespace DamnTools.SqlTodoExplorer.Services 2 | { 3 | public class Routine 4 | { 5 | public int? Id { get; set; } 6 | public string Database { get; set; } 7 | public string Schema { get; set; } 8 | public string Name { get; set; } 9 | public string FullName { get; set; } 10 | public RoutineType Type { get; set; } 11 | public string Definition { get; set; } 12 | 13 | public override string ToString() 14 | { 15 | return string.Format("{0}.{1}", this.Database, this.FullName); 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /Source/SqlTodoExplorer/Services/RoutineType.cs: -------------------------------------------------------------------------------- 1 | namespace DamnTools.SqlTodoExplorer.Services 2 | { 3 | public enum RoutineType 4 | { 5 | StoredProcedure = 1, 6 | Function = 2 7 | } 8 | } -------------------------------------------------------------------------------- /Source/SqlTodoExplorer/Services/ScriptService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using EnvDTE; 3 | using EnvDTE80; 4 | using Microsoft.SqlServer.Management.UI.VSIntegration.Editors; 5 | 6 | namespace DamnTools.SqlTodoExplorer.Services 7 | { 8 | public class ScriptService : IScriptService 9 | { 10 | private readonly IScriptFactory _scriptFactory; 11 | private readonly _DTE _dte; 12 | 13 | public ScriptService(IScriptFactory scriptFactory, _DTE dte) 14 | { 15 | if (scriptFactory == null) throw new ArgumentNullException("scriptFactory"); 16 | if (dte == null) throw new ArgumentNullException("dte"); 17 | 18 | _scriptFactory = scriptFactory; 19 | _dte = dte; 20 | } 21 | 22 | public void CreateNewScript(string content) 23 | { 24 | Document activeDocument = null; 25 | 26 | _scriptFactory.CreateNewBlankScript(ScriptType.Sql); 27 | 28 | var dte = _dte.DTE as DTE2; 29 | if (dte != null) 30 | { 31 | activeDocument = dte.ActiveDocument; 32 | } 33 | 34 | if (activeDocument != null) 35 | { 36 | var ts = activeDocument.Selection as TextSelection; 37 | if (ts != null) 38 | { 39 | ts.Insert(content, (int)vsInsertFlags.vsInsertFlagsCollapseToStart); 40 | } 41 | } 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /Source/SqlTodoExplorer/Services/ServerConnectionInfo.cs: -------------------------------------------------------------------------------- 1 | namespace DamnTools.SqlTodoExplorer.Services 2 | { 3 | public class ServerConnectionInfo 4 | { 5 | public string ServerName { get; set; } 6 | public bool UseIntegratedSecurity { get; set; } 7 | public string UserName { get; set; } 8 | public string Password { get; set; } 9 | 10 | public override string ToString() 11 | { 12 | return string.Format("[ServerName:{0}],[UseIntegratedSecurity:{1}],[UserName:{2}],[Password:{3}]", this.ServerName, this.UseIntegratedSecurity, this.UserName, this.Password); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Source/SqlTodoExplorer/Services/ServerConnectionService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using Microsoft.SqlServer.Management.Common; 4 | using Microsoft.SqlServer.Management.Smo.RegSvrEnum; 5 | using Microsoft.SqlServer.Management.UI.VSIntegration.Editors; 6 | using Microsoft.SqlServer.Management.UI.VSIntegration.ObjectExplorer; 7 | 8 | namespace DamnTools.SqlTodoExplorer.Services 9 | { 10 | public class ServerConnectionService : IServerConnectionService 11 | { 12 | private readonly IScriptFactory _scriptFactory; 13 | private readonly IObjectExplorerService _objectExplorerService; 14 | 15 | public ServerConnectionService(IScriptFactory scriptFactory, IObjectExplorerService objectExplorerService) 16 | { 17 | if (scriptFactory == null) throw new ArgumentNullException("scriptFactory"); 18 | if (objectExplorerService == null) throw new ArgumentNullException("objectExplorerService"); 19 | 20 | _scriptFactory = scriptFactory; 21 | _objectExplorerService = objectExplorerService; 22 | } 23 | 24 | public ServerConnectionInfo GetCurrentConnection() 25 | { 26 | ServerConnectionInfo currentConnection = null; 27 | try 28 | { 29 | UIConnectionInfo connectionInfo = null; 30 | 31 | if (_scriptFactory.CurrentlyActiveWndConnectionInfo != null) 32 | { 33 | connectionInfo = _scriptFactory.CurrentlyActiveWndConnectionInfo.UIConnectionInfo; 34 | } 35 | 36 | if (connectionInfo != null) 37 | { 38 | currentConnection = new ServerConnectionInfo 39 | { 40 | ServerName = connectionInfo.ServerName, 41 | UseIntegratedSecurity = string.IsNullOrEmpty(connectionInfo.Password), 42 | UserName = connectionInfo.UserName, 43 | Password = connectionInfo.Password 44 | }; 45 | } 46 | else 47 | { 48 | int nodeCount; 49 | INodeInformation[] nodes; 50 | 51 | _objectExplorerService.GetSelectedNodes(out nodeCount, out nodes); 52 | 53 | if (nodes.Length > 0) 54 | { 55 | var info = nodes[0].Connection as SqlConnectionInfo; 56 | if (info != null) 57 | { 58 | currentConnection = new ServerConnectionInfo 59 | { 60 | ServerName = info.ServerName, 61 | UseIntegratedSecurity = info.UseIntegratedSecurity, 62 | UserName = info.UserName, 63 | Password = info.Password 64 | }; 65 | } 66 | } 67 | } 68 | } 69 | catch (Exception ex) 70 | { 71 | Trace.TraceError("Error getting current connection: {0}", ex); 72 | } 73 | return currentConnection; 74 | } 75 | } 76 | } -------------------------------------------------------------------------------- /Source/SqlTodoExplorer/Services/SmoServerGateway.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Data; 4 | using System.Data.SqlClient; 5 | using System.Diagnostics; 6 | using System.Linq; 7 | using Microsoft.SqlServer.Management.Common; 8 | using Microsoft.SqlServer.Management.Smo; 9 | 10 | namespace DamnTools.SqlTodoExplorer.Services 11 | { 12 | public class SmoServerGateway : IServerGateway 13 | { 14 | private readonly ServerConnection _serverConnection; 15 | private readonly Server _server; 16 | 17 | public SmoServerGateway(ServerConnectionInfo info) 18 | { 19 | _serverConnection = info.UseIntegratedSecurity 20 | ? new ServerConnection(info.ServerName) 21 | : new ServerConnection(info.ServerName, info.UserName, info.Password); 22 | 23 | _server = new Server(_serverConnection); 24 | } 25 | 26 | public IReadOnlyList GetDatabases() 27 | { 28 | _server.Databases.Refresh(); 29 | var databases = _server.Databases.Cast().Select(t => t.Name).ToList(); 30 | return databases; 31 | } 32 | 33 | public IReadOnlyList GetRoutines(IEnumerable databases = null) 34 | { 35 | if (databases == null) databases = GetDatabases(); 36 | var routines = new List(); 37 | foreach (var database in databases) 38 | { 39 | try 40 | { 41 | var sqlRoutinesCommandText = string.Format(Resources.SQL_Routines, database); 42 | using (var reader = _serverConnection.ExecuteReader(sqlRoutinesCommandText)) 43 | { 44 | routines.AddRange(GetRoutinesFromReader(reader, database)); 45 | } 46 | } 47 | catch (ExecutionFailureException e) 48 | { 49 | Trace.TraceError(e.ToString()); 50 | } 51 | } 52 | return routines; 53 | } 54 | 55 | public Routine GetRoutine(string database, int routineId) 56 | { 57 | if (string.IsNullOrWhiteSpace(database)) throw new ArgumentNullException("database"); 58 | 59 | var sqlRoutinesCommandText = string.Format(Resources.SQL_Routine, database, routineId); 60 | using (var reader = _serverConnection.ExecuteReader(sqlRoutinesCommandText)) 61 | { 62 | return GetRoutinesFromReader(reader, database).FirstOrDefault(); 63 | } 64 | } 65 | 66 | public List GetRoutinesFromReader(SqlDataReader reader, string database) 67 | { 68 | var records = reader.Cast() 69 | .Select(t => new 70 | { 71 | Id = reader.Get("ROUTINE_OBJECTID"), 72 | Schema = reader.Get("ROUTINE_SCHEMA"), 73 | Name = reader.Get("ROUTINE_NAME"), 74 | FullName = reader.Get("ROUTINE_FULLNAME"), 75 | Type = DbEnumTypeHelper.GetRoutineType(reader.Get("ROUTINE_TYPE")), 76 | Definition = reader.Get("ROUTINE_DEFINITION") 77 | }); 78 | 79 | var routines = (from record in records 80 | group record by record.Id 81 | into groupedRoutines 82 | let routineData = groupedRoutines.First() 83 | let hasRoutineDefinition = groupedRoutines.Any(t => t.Definition != null) 84 | select new Routine 85 | { 86 | Id = routineData.Id, 87 | Database = database, 88 | Schema = routineData.Schema, 89 | Name = routineData.Name, 90 | FullName = routineData.FullName, 91 | Type = routineData.Type, 92 | Definition = hasRoutineDefinition ? string.Concat(groupedRoutines.Where(t => t.Definition != null).SelectMany(t => t.Definition)) : null 93 | }).ToList(); 94 | 95 | return routines; 96 | } 97 | } 98 | } -------------------------------------------------------------------------------- /Source/SqlTodoExplorer/Services/SqlDataReaderEx.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Data.SqlClient; 3 | 4 | namespace DamnTools.SqlTodoExplorer.Services 5 | { 6 | public static class SqlDataReaderEx 7 | { 8 | public static T Get(this SqlDataReader reader, string fieldName) 9 | { 10 | int ordinal; 11 | try 12 | { 13 | ordinal = reader.GetOrdinal(fieldName); 14 | } 15 | catch (Exception) 16 | { 17 | throw new IndexOutOfRangeException(string.Format("Field name '{0}' not found.", fieldName)); 18 | } 19 | return !reader.IsDBNull(ordinal) ? (T)reader.GetValue(ordinal) : default(T); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Source/SqlTodoExplorer/Services/TodoExplorer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using Microsoft.SqlServer.Management.UI.VSIntegration; 4 | using Microsoft.SqlServer.Management.UI.VSIntegration.ObjectExplorer; 5 | 6 | namespace DamnTools.SqlTodoExplorer.Services 7 | { 8 | public static class TodoExplorer 9 | { 10 | public static ITodoExplorerManager CreateFromCurrentConnection() 11 | { 12 | var explorerService = (IObjectExplorerService)ServiceCache.ServiceProvider.GetService(typeof(IObjectExplorerService)); 13 | var scriptFactory = ServiceCache.ScriptFactory; 14 | var connectionService = new ServerConnectionService(scriptFactory, explorerService); 15 | var connectionInfo = connectionService.GetCurrentConnection(); 16 | if (connectionInfo == null) throw new Exception("Cannot create todo explorer services because cannot get the current connection."); 17 | Trace.TraceInformation("ConnectionInfo: {0}", connectionInfo); 18 | var serverGateway = new SmoServerGateway(connectionInfo); 19 | var dte = ServiceCache.ExtensibilityModel; 20 | var scriptService = new ScriptService(scriptFactory, dte); 21 | var todoPatternService = new TodoPatternService(); 22 | var todoExplorerService = new TodoExplorerManager(serverGateway, scriptService, todoPatternService); 23 | return todoExplorerService; 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /Source/SqlTodoExplorer/Services/TodoExplorerManager.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Diagnostics; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Text.RegularExpressions; 6 | 7 | namespace DamnTools.SqlTodoExplorer.Services 8 | { 9 | public class TodoExplorerManager : ITodoExplorerManager 10 | { 11 | private readonly IServerGateway _serverGateway; 12 | private readonly IScriptService _scriptService; 13 | private readonly ITodoPatternService _todoPatternService; 14 | private readonly string[] _databaseExclusionList; 15 | 16 | public TodoExplorerManager( 17 | IServerGateway serverGateway, 18 | IScriptService scriptService, 19 | ITodoPatternService todoPatternService) 20 | { 21 | _serverGateway = serverGateway; 22 | _scriptService = scriptService; 23 | _todoPatternService = todoPatternService; 24 | 25 | _databaseExclusionList = Resources.Database_ExclusionList.Split(','); 26 | } 27 | 28 | public IReadOnlyList GetDatabases(bool includeSystemDatabases = false) 29 | { 30 | if (includeSystemDatabases) 31 | { 32 | return _serverGateway.GetDatabases().ToList(); 33 | } 34 | return _serverGateway.GetDatabases() 35 | .Except(_databaseExclusionList) 36 | .ToList(); 37 | } 38 | 39 | public IReadOnlyList GetTodoItems(string database = null, ITodoPattern pattern = null, bool includeSystemDatabases = false) 40 | { 41 | IReadOnlyList databases = database != null ? new[] { database } : this.GetDatabases(includeSystemDatabases); 42 | IReadOnlyList patterns = pattern != null ? new[] { pattern } : this.GetTodoPatterns(); 43 | return GetTodoItems(databases, patterns); 44 | } 45 | 46 | public IReadOnlyList GetTodoItems(IEnumerable databases, IEnumerable patterns) 47 | { 48 | var sw = Stopwatch.StartNew(); 49 | var todoItems = new List(); 50 | var routines = _serverGateway.GetRoutines(databases); 51 | Trace.TraceInformation("GetRoutines elapsed milliseconds: {0}", sw.ElapsedMilliseconds); 52 | sw.Restart(); 53 | foreach (var routine in routines.Where(t => t.Id.HasValue && 54 | !string.IsNullOrWhiteSpace(t.Definition))) 55 | { 56 | foreach (var todoPattern in patterns.OfType()) 57 | { 58 | var regex = todoPattern.PatternRegex; 59 | var matches = regex.Matches(routine.Definition); 60 | int count = 0; 61 | foreach (Match match in matches) 62 | { 63 | count++; 64 | var tag = match.Groups["TAG"]; 65 | var todoItem = new TodoItem 66 | { 67 | Tag = tag.Success ? match.Groups["TAG"].Value : "TODO", 68 | Text = match.Value, 69 | TextIndex = match.Index, 70 | TextLength = match.Length, 71 | TextOccurrence = count, 72 | Pattern = todoPattern, 73 | Database = routine.Database, 74 | RoutineId = routine.Id.Value, 75 | RoutineSchema = routine.Schema, 76 | RoutineName = routine.Name, 77 | RoutineType = routine.Type 78 | }; 79 | todoItems.Add(todoItem); 80 | } 81 | } 82 | } 83 | sw.Stop(); 84 | Trace.TraceInformation("Regex parsing elapsed milliseconds: {0}", sw.ElapsedMilliseconds); 85 | return todoItems; 86 | } 87 | 88 | public IReadOnlyList GetTodoPatterns() 89 | { 90 | return _todoPatternService.GetTodoPatterns(); 91 | } 92 | 93 | public void NavigateTo(TodoItem todoItem) 94 | { 95 | this.ScriptAsAlter(todoItem); 96 | 97 | // TODO: move the caret to the todo position (vedi: GotoLine, MoveToPoint, MoveToLineAndOffset, MoveToAbsoluteOffset, FindPattern) 98 | } 99 | 100 | public void ScriptAsCreate(TodoItem todoItem) 101 | { 102 | var routine = _serverGateway.GetRoutine(todoItem.Database, todoItem.RoutineId); 103 | _scriptService.CreateNewScript(routine.Definition); 104 | } 105 | 106 | public void ScriptAsAlter(TodoItem todoItem) 107 | { 108 | var routine = _serverGateway.GetRoutine(todoItem.Database, todoItem.RoutineId); 109 | 110 | var definition = Regex.Replace(routine.Definition, Resources.ScriptAsAlter_ReplaceRegex, "ALTER", RegexOptions.IgnoreCase | RegexOptions.Multiline); 111 | 112 | var sb = new StringBuilder(); 113 | sb.AppendFormat("USE [{0}]", todoItem.Database); 114 | sb.AppendLine(); 115 | sb.AppendLine("GO"); 116 | sb.Append(definition); 117 | 118 | _scriptService.CreateNewScript(sb.ToString()); 119 | } 120 | } 121 | } -------------------------------------------------------------------------------- /Source/SqlTodoExplorer/Services/TodoItem.cs: -------------------------------------------------------------------------------- 1 | namespace DamnTools.SqlTodoExplorer.Services 2 | { 3 | public class TodoItem 4 | { 5 | public string Tag { get; set; } 6 | public string Text { get; set; } 7 | public int TextIndex { get; set; } 8 | public int TextLength { get; set; } 9 | public int TextOccurrence { get; set; } 10 | public ITodoPattern Pattern { get; set; } 11 | public string Database { get; set; } 12 | public int RoutineId { get; set; } 13 | public string RoutineSchema { get; set; } 14 | public string RoutineName { get; set; } 15 | public RoutineType RoutineType { get; set; } 16 | 17 | public override string ToString() 18 | { 19 | return string.Format("{0}: {1}", this.RoutineId, this.Text); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /Source/SqlTodoExplorer/Services/TodoPattern.cs: -------------------------------------------------------------------------------- 1 | using System.Text.RegularExpressions; 2 | using System.Xml.Serialization; 3 | 4 | namespace DamnTools.SqlTodoExplorer.Services 5 | { 6 | public class TodoPattern : ITodoPattern 7 | { 8 | public int Id { get; set; } 9 | 10 | public string Title { get; set; } 11 | 12 | public string SearchPattern { get; set; } 13 | 14 | private volatile Regex _patternRegex; 15 | private readonly object _patternRegexSync = new object(); 16 | 17 | [XmlIgnore] 18 | public Regex PatternRegex 19 | { 20 | get 21 | { 22 | if (string.IsNullOrEmpty(this.SearchPattern)) return null; 23 | if (_patternRegex == null) 24 | { 25 | lock (_patternRegexSync) 26 | { 27 | if (_patternRegex == null) 28 | { 29 | _patternRegex = new Regex(this.SearchPattern, RegexOptions.IgnoreCase); 30 | } 31 | } 32 | } 33 | else 34 | { 35 | if (_patternRegex.ToString() != this.SearchPattern) 36 | { 37 | lock (_patternRegexSync) 38 | { 39 | if (_patternRegex == null || _patternRegex.ToString() != this.SearchPattern) 40 | { 41 | _patternRegex = new Regex(this.SearchPattern, RegexOptions.IgnoreCase); 42 | } 43 | } 44 | } 45 | } 46 | return _patternRegex; 47 | } 48 | } 49 | 50 | public override string ToString() 51 | { 52 | return this.Title; 53 | } 54 | } 55 | } -------------------------------------------------------------------------------- /Source/SqlTodoExplorer/Services/TodoPatternService.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.IO; 3 | using System.Xml.Serialization; 4 | 5 | namespace DamnTools.SqlTodoExplorer.Services 6 | { 7 | public class TodoPatternService : ITodoPatternService 8 | { 9 | public IReadOnlyList GetTodoPatterns() 10 | { 11 | using (var reader = new StringReader(Resources.DefaultTodoPatterns)) 12 | { 13 | var serializer = new XmlSerializer(typeof(List)); 14 | var todoPatterns = (List)serializer.Deserialize(reader); 15 | return todoPatterns; 16 | } 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Source/SqlTodoExplorer/Services/WindowsManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | using System.Windows.Forms; 4 | using DamnTools.SqlTodoExplorer.Presentation; 5 | using DamnTools.SqlTodoExplorer.Presentation.Model; 6 | using EnvDTE; 7 | using EnvDTE80; 8 | 9 | namespace DamnTools.SqlTodoExplorer.Services 10 | { 11 | public class WindowsManager : IWindowsManager 12 | { 13 | private readonly _DTE _dte; 14 | 15 | public WindowsManager(_DTE dte) 16 | { 17 | _dte = dte; 18 | } 19 | 20 | public Window2 ShowWindow(AddIn addIn, string title, bool isFloating = true, int width = 450, int height = 450) 21 | where T : UserControl 22 | { 23 | Windows2 toolWindows = _dte.Windows as Windows2; 24 | if (toolWindows != null) 25 | { 26 | var assembly = Assembly.GetExecutingAssembly(); 27 | var location = assembly.Location; 28 | var type = typeof(T); 29 | object controlObject = null; 30 | 31 | var toolWindow = (Window2)toolWindows.CreateToolWindow2(addIn, location, type.FullName, title, Guid.NewGuid().ToString(), ref controlObject); 32 | 33 | var dataService = new PresentationDataService(); 34 | var presenter = new SqlTodoExplorerPresenter((ISqlTodoExplorerView)controlObject, dataService); 35 | presenter.Init(); 36 | 37 | toolWindow.WindowState = vsWindowState.vsWindowStateNormal; 38 | toolWindow.IsFloating = isFloating; 39 | toolWindow.Width = width; 40 | toolWindow.Height = height; 41 | toolWindow.Visible = true; 42 | 43 | return toolWindow; 44 | } 45 | return null; 46 | } 47 | 48 | // TODO: should we implement a Load and Save method to store the state of the window, or is up to the visual studio IDE to do this? 49 | } 50 | } -------------------------------------------------------------------------------- /Source/SqlTodoExplorer/SqlTodoExplorer.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 8.0.30424 7 | 2.0 8 | {54C786E5-FD14-4036-92AE-E9F25B71534B} 9 | Library 10 | 11 | 12 | false 13 | DamnTools.SqlTodoExplorer 14 | .\bin\ 15 | v4.5 16 | 17 | SAK 18 | SAK 19 | SAK 20 | SAK 21 | 22 | 23 | true 24 | false 25 | .\bin\Debug\ 26 | false 27 | DEBUG;TRACE 28 | 4 29 | false 30 | false 31 | 32 | 33 | 34 | 35 | false 36 | true 37 | .\bin\Release\ 38 | false 39 | TRACE 40 | 4 41 | false 42 | false 43 | SsmsTodoExplorerAddin.xml 44 | 45 | 46 | DamnTools.SqlTodoExplorer 47 | 48 | 49 | 50 | False 51 | 52 | 53 | 54 | 55 | 56 | False 57 | ..\..\..\..\Program Files (x86)\Microsoft SQL Server\110\SDK\Assemblies\Microsoft.SqlServer.Smo.dll 58 | 59 | 60 | 61 | 62 | ..\..\..\..\..\..\..\..\Program Files (x86)\Microsoft SQL Server\110\Tools\Binn\ManagementStudio\SqlPackageBase.dll 63 | 64 | 65 | ..\..\..\..\..\..\..\..\Program Files (x86)\Microsoft SQL Server\110\Tools\Binn\ManagementStudio\SqlWorkbench.Interfaces.dll 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | Code 79 | 80 | 81 | Code 82 | 83 | 84 | 85 | 86 | 87 | 88 | UserControl 89 | 90 | 91 | SqlTodoExplorerView.cs 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | True 105 | True 106 | Resources.resx 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | True 118 | True 119 | Resources.resx 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | {80CC9F66-E7D8-4DDD-85B6-D9E6CD0E93E2} 138 | 8 139 | 0 140 | 0 141 | primary 142 | False 143 | False 144 | 145 | 146 | {26AD1324-4B7C-44BC-84F8-B86AED45729F} 147 | 10 148 | 0 149 | 0 150 | primary 151 | False 152 | False 153 | 154 | 155 | {1A31287A-4D7D-413E-8E32-3B374931BD89} 156 | 8 157 | 0 158 | 0 159 | primary 160 | False 161 | False 162 | 163 | 164 | {2CE2370E-D744-4936-A090-3FFFE667B0E1} 165 | 9 166 | 0 167 | 0 168 | primary 169 | False 170 | False 171 | 172 | 173 | {1CBA492E-7263-47BB-87FE-639000619B15} 174 | 8 175 | 0 176 | 0 177 | primary 178 | False 179 | False 180 | 181 | 182 | {00020430-0000-0000-C000-000000000046} 183 | 2 184 | 0 185 | 0 186 | primary 187 | False 188 | False 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | SqlTodoExplorerView.cs 207 | 208 | 209 | SqlTodoExplorerView.cs 210 | 211 | 212 | SqlTodoExplorerView.cs 213 | 214 | 215 | Designer 216 | 217 | 218 | Designer 219 | 220 | 221 | ResXFileCodeGenerator 222 | Resources.Designer.cs 223 | Designer 224 | 225 | 226 | PublicResXFileCodeGenerator 227 | Designer 228 | Resources.Designer.cs 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | --------------------------------------------------------------------------------