├── .gitignore
├── CODE_OF_CONDUCT.md
├── LICENSE
├── README.md
├── build
├── PackDbUp.cmd
└── README.md
└── src
├── dbup-cli.integration-tests
├── CockroachDbTests.cs
├── DockerBasedTest.cs
├── MySqlTests.cs
├── PostgreSqlTests.cs
├── README.md
├── Scripts
│ ├── CockroachDb
│ │ ├── EmptyScript
│ │ │ ├── 001.sql
│ │ │ └── dbup.yml
│ │ ├── JournalTableScript
│ │ │ ├── 001.sql
│ │ │ └── dbup.yml
│ │ └── Timeout
│ │ │ ├── 001.sql
│ │ │ └── dbup.yml
│ ├── MySql
│ │ ├── EmptyScript
│ │ │ ├── 001.sql
│ │ │ └── dbup.yml
│ │ ├── JournalTableScript
│ │ │ ├── 001.sql
│ │ │ └── dbup.yml
│ │ └── Timeout
│ │ │ ├── 001.sql
│ │ │ └── dbup.yml
│ ├── PostgreSql
│ │ ├── EmptyScript
│ │ │ ├── 001.sql
│ │ │ └── dbup.yml
│ │ ├── JournalTableScript
│ │ │ ├── 001.sql
│ │ │ └── dbup.yml
│ │ └── Timeout
│ │ │ ├── 001.sql
│ │ │ └── dbup.yml
│ └── SqlServer
│ │ ├── EmptyScript
│ │ ├── 001.sql
│ │ └── dbup.yml
│ │ ├── JournalTableScript
│ │ ├── 001.sql
│ │ └── dbup.yml
│ │ └── Timeout
│ │ ├── 001.sql
│ │ └── dbup.yml
├── SqlServerTests.cs
└── dbup-cli.integration-tests.csproj
├── dbup-cli.sln
├── dbup-cli.tests.core
├── TestInfrastructure
│ ├── CaptureLogsLogger.cs
│ ├── CaptureLogsLoggerExtensions.cs
│ ├── EmptyReader.cs
│ ├── RecordingDataParameterCollection.cs
│ ├── RecordingDbCommand.cs
│ ├── RecordingDbConnection.cs
│ ├── RecordingDbDataParameter.cs
│ ├── RecordingDbTransaction.cs
│ ├── ScriptReader.cs
│ ├── Scrubbers.cs
│ ├── SubstitutedConnectionConnectionManager.cs
│ ├── TestConnectionManager.cs
│ ├── TestDatabaseExtension.cs
│ └── TestScriptProvider.cs
└── dbup-cli.tests.core.csproj
├── dbup-cli.tests
├── ConfigLoaderTests.cs
├── ConfigurationHelperTests.cs
├── EnvVariableSubstitutionTests.cs
├── FilterTests.cs
├── NamingOptionsTests.cs
├── ScriptProviderHelperTests.cs
├── Scripts
│ ├── Config
│ │ ├── .env
│ │ ├── DotEnv-CurrentFolder
│ │ │ └── .env
│ │ ├── DotEnv-VarsOverride
│ │ │ ├── ConfigFolder
│ │ │ │ ├── .env
│ │ │ │ └── dotenv-vars.yml
│ │ │ ├── CurrentFolder
│ │ │ │ └── .env
│ │ │ ├── file3.env
│ │ │ └── file4.env
│ │ ├── Encoding
│ │ │ └── c001.sql
│ │ ├── FilterRegex
│ │ │ ├── d001.sql
│ │ │ ├── d01.sql
│ │ │ ├── d0a1.sql
│ │ │ ├── d0aa1.sql
│ │ │ └── d0b1.sql
│ │ ├── FilterWildcard
│ │ │ ├── c001.sql
│ │ │ ├── c01.sql
│ │ │ ├── c0a1.sql
│ │ │ ├── c0aa1.sql
│ │ │ └── c0b1.sql
│ │ ├── FilterWithFullPath
│ │ │ ├── e001.sql
│ │ │ ├── e01.sql
│ │ │ ├── e0a1.sql
│ │ │ ├── e0aa1.sql
│ │ │ └── e0b1.sql
│ │ ├── MarkAsExecuted
│ │ │ └── c001.sql
│ │ ├── Naming
│ │ │ └── SubFolder
│ │ │ │ └── 001.sql
│ │ ├── NoScripts
│ │ │ └── FolderShouldExists.txt
│ │ ├── OneScript
│ │ │ └── c001.sql
│ │ ├── Status
│ │ │ ├── Scripts
│ │ │ │ └── c001.sql
│ │ │ ├── file1.env
│ │ │ ├── file2.env
│ │ │ └── status.yml
│ │ ├── Vars
│ │ │ └── c001.sql
│ │ ├── c001.sql
│ │ ├── disable-vars.yml
│ │ ├── dotenv-vars.yml
│ │ ├── encoding.yml
│ │ ├── env-vars.yml
│ │ ├── filter.yml
│ │ ├── invalid-provider.yml
│ │ ├── invalid-transaction.yml
│ │ ├── invalid-vars.yml
│ │ ├── journalTo-null.yml
│ │ ├── journalTo.yml
│ │ ├── log.yml
│ │ ├── mark-as-executed.yml
│ │ ├── min.yml
│ │ ├── naming.yml
│ │ ├── no-scripts.yml
│ │ ├── no-vars.yml
│ │ ├── noscripts.yml
│ │ ├── onescript.yml
│ │ ├── script.yml
│ │ ├── syntax-error.yml
│ │ ├── timeout.yml
│ │ ├── tran.yml
│ │ ├── varC.env
│ │ ├── varD.env
│ │ ├── vars.yml
│ │ └── wrongversion.yml
│ └── Default
│ │ ├── 001.sql
│ │ ├── 002.sql
│ │ ├── SubFolder1
│ │ ├── 003.sql
│ │ └── 004.sql
│ │ └── SubFolder2
│ │ └── 005.sql
├── ToolEngineTests.cs
├── VariableSubstitutionTests.cs
└── dbup-cli.tests.csproj
└── dbup-cli
├── CliEnvironment.cs
├── CommandLineOptions
├── DropOptions.cs
├── InitOptions.cs
├── MarkAsExecutedOptions.cs
├── OptionsBase.cs
├── StatusOptions.cs
├── UpgradeOptions.cs
└── VerbosityBase.cs
├── ConfigFile
├── ConfigFile.cs
├── Journal.cs
├── Migration.cs
├── NamingOptions.cs
├── Provider.cs
├── ScriptBatch.cs
└── Transaction.cs
├── ConfigLoader.cs
├── ConfigurationHelper.cs
├── Constants.cs
├── DbUpCustomization
├── AzureSqlDatabaseWithIntegratedSecurity.cs
├── ConsoleLogger.cs
├── CustomFileSystemScriptOptions.cs
└── CustomFileSystemScriptProvider.cs
├── DefaultOptions
└── dbup.yml
├── Error.cs
├── How-to-add-a-new-db.md
├── How-to-create-a-new-release.md
├── IEnvironment.cs
├── Program.cs
├── README.md
├── ROADMAP.md
├── ResultBuilder.cs
├── ScriptProviderHelper.cs
├── StringUtils.cs
├── ToolEngine.cs
└── dbup-cli.csproj
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 | ##
4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
5 |
6 | # User-specific files
7 | *.suo
8 | *.user
9 | *.userosscache
10 | *.sln.docstates
11 |
12 | # User-specific files (MonoDevelop/Xamarin Studio)
13 | *.userprefs
14 |
15 | # Build results
16 | [Dd]ebug/
17 | [Dd]ebugPublic/
18 | [Rr]elease/
19 | [Rr]eleases/
20 | x64/
21 | x86/
22 | bld/
23 | [Bb]in/
24 | [Oo]bj/
25 | [Ll]og/
26 |
27 | # Visual Studio 2015/2017 cache/options directory
28 | .vs/
29 | # Uncomment if you have tasks that create the project's static files in wwwroot
30 | #wwwroot/
31 |
32 | # Visual Studio 2017 auto generated files
33 | Generated\ Files/
34 |
35 | # MSTest test Results
36 | [Tt]est[Rr]esult*/
37 | [Bb]uild[Ll]og.*
38 |
39 | # NUNIT
40 | *.VisualState.xml
41 | TestResult.xml
42 |
43 | # Build Results of an ATL Project
44 | [Dd]ebugPS/
45 | [Rr]eleasePS/
46 | dlldata.c
47 |
48 | # Benchmark Results
49 | BenchmarkDotNet.Artifacts/
50 |
51 | # .NET Core
52 | project.lock.json
53 | project.fragment.lock.json
54 | artifacts/
55 | **/Properties/launchSettings.json
56 |
57 | # StyleCop
58 | StyleCopReport.xml
59 |
60 | # Files built by Visual Studio
61 | *_i.c
62 | *_p.c
63 | *_i.h
64 | *.ilk
65 | *.meta
66 | *.obj
67 | *.iobj
68 | *.pch
69 | *.pdb
70 | *.ipdb
71 | *.pgc
72 | *.pgd
73 | *.rsp
74 | *.sbr
75 | *.tlb
76 | *.tli
77 | *.tlh
78 | *.tmp
79 | *.tmp_proj
80 | *.log
81 | *.vspscc
82 | *.vssscc
83 | .builds
84 | *.pidb
85 | *.svclog
86 | *.scc
87 |
88 | # Chutzpah Test files
89 | _Chutzpah*
90 |
91 | # Visual C++ cache files
92 | ipch/
93 | *.aps
94 | *.ncb
95 | *.opendb
96 | *.opensdf
97 | *.sdf
98 | *.cachefile
99 | *.VC.db
100 | *.VC.VC.opendb
101 |
102 | # Visual Studio profiler
103 | *.psess
104 | *.vsp
105 | *.vspx
106 | *.sap
107 |
108 | # Visual Studio Trace Files
109 | *.e2e
110 |
111 | # TFS 2012 Local Workspace
112 | $tf/
113 |
114 | # Guidance Automation Toolkit
115 | *.gpState
116 |
117 | # ReSharper is a .NET coding add-in
118 | _ReSharper*/
119 | *.[Rr]e[Ss]harper
120 | *.DotSettings.user
121 |
122 | # JustCode is a .NET coding add-in
123 | .JustCode
124 |
125 | # TeamCity is a build add-in
126 | _TeamCity*
127 |
128 | # DotCover is a Code Coverage Tool
129 | *.dotCover
130 |
131 | # AxoCover is a Code Coverage Tool
132 | .axoCover/*
133 | !.axoCover/settings.json
134 |
135 | # Visual Studio code coverage results
136 | *.coverage
137 | *.coveragexml
138 |
139 | # NCrunch
140 | _NCrunch_*
141 | .*crunch*.local.xml
142 | nCrunchTemp_*
143 |
144 | # MightyMoose
145 | *.mm.*
146 | AutoTest.Net/
147 |
148 | # Web workbench (sass)
149 | .sass-cache/
150 |
151 | # Installshield output folder
152 | [Ee]xpress/
153 |
154 | # DocProject is a documentation generator add-in
155 | DocProject/buildhelp/
156 | DocProject/Help/*.HxT
157 | DocProject/Help/*.HxC
158 | DocProject/Help/*.hhc
159 | DocProject/Help/*.hhk
160 | DocProject/Help/*.hhp
161 | DocProject/Help/Html2
162 | DocProject/Help/html
163 |
164 | # Click-Once directory
165 | publish/
166 |
167 | # Publish Web Output
168 | *.[Pp]ublish.xml
169 | *.azurePubxml
170 | # Note: Comment the next line if you want to checkin your web deploy settings,
171 | # but database connection strings (with potential passwords) will be unencrypted
172 | *.pubxml
173 | *.publishproj
174 |
175 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
176 | # checkin your Azure Web App publish settings, but sensitive information contained
177 | # in these scripts will be unencrypted
178 | PublishScripts/
179 |
180 | # NuGet Packages
181 | *.nupkg
182 | # The packages folder can be ignored because of Package Restore
183 | **/[Pp]ackages/*
184 | # except build/, which is used as an MSBuild target.
185 | !**/[Pp]ackages/build/
186 | # Uncomment if necessary however generally it will be regenerated when needed
187 | #!**/[Pp]ackages/repositories.config
188 | # NuGet v3's project.json files produces more ignorable files
189 | *.nuget.props
190 | *.nuget.targets
191 |
192 | # Microsoft Azure Build Output
193 | csx/
194 | *.build.csdef
195 |
196 | # Microsoft Azure Emulator
197 | ecf/
198 | rcf/
199 |
200 | # Windows Store app package directories and files
201 | AppPackages/
202 | BundleArtifacts/
203 | Package.StoreAssociation.xml
204 | _pkginfo.txt
205 | *.appx
206 |
207 | # Visual Studio cache files
208 | # files ending in .cache can be ignored
209 | *.[Cc]ache
210 | # but keep track of directories ending in .cache
211 | !*.[Cc]ache/
212 |
213 | # Others
214 | ClientBin/
215 | ~$*
216 | *~
217 | *.dbmdl
218 | *.dbproj.schemaview
219 | *.jfm
220 | *.pfx
221 | *.publishsettings
222 | orleans.codegen.cs
223 |
224 | # Including strong name files can present a security risk
225 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
226 | #*.snk
227 |
228 | # Since there are multiple workflows, uncomment next line to ignore bower_components
229 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
230 | #bower_components/
231 |
232 | # RIA/Silverlight projects
233 | Generated_Code/
234 |
235 | # Backup & report files from converting an old project file
236 | # to a newer Visual Studio version. Backup files are not needed,
237 | # because we have git ;-)
238 | _UpgradeReport_Files/
239 | Backup*/
240 | UpgradeLog*.XML
241 | UpgradeLog*.htm
242 | ServiceFabricBackup/
243 | *.rptproj.bak
244 |
245 | # SQL Server files
246 | *.mdf
247 | *.ldf
248 | *.ndf
249 |
250 | # Business Intelligence projects
251 | *.rdl.data
252 | *.bim.layout
253 | *.bim_*.settings
254 | *.rptproj.rsuser
255 |
256 | # Microsoft Fakes
257 | FakesAssemblies/
258 |
259 | # GhostDoc plugin setting file
260 | *.GhostDoc.xml
261 |
262 | # Node.js Tools for Visual Studio
263 | .ntvs_analysis.dat
264 | node_modules/
265 |
266 | # Visual Studio 6 build log
267 | *.plg
268 |
269 | # Visual Studio 6 workspace options file
270 | *.opt
271 |
272 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
273 | *.vbw
274 |
275 | # Visual Studio LightSwitch build output
276 | **/*.HTMLClient/GeneratedArtifacts
277 | **/*.DesktopClient/GeneratedArtifacts
278 | **/*.DesktopClient/ModelManifest.xml
279 | **/*.Server/GeneratedArtifacts
280 | **/*.Server/ModelManifest.xml
281 | _Pvt_Extensions
282 |
283 | # Paket dependency manager
284 | .paket/paket.exe
285 | paket-files/
286 |
287 | # FAKE - F# Make
288 | .fake/
289 |
290 | # JetBrains Rider
291 | .idea/
292 | *.sln.iml
293 |
294 | # CodeRush
295 | .cr/
296 |
297 | # Python Tools for Visual Studio (PTVS)
298 | __pycache__/
299 | *.pyc
300 |
301 | # Cake - Uncomment if you are using it
302 | # tools/**
303 | # !tools/packages.config
304 |
305 | # Tabs Studio
306 | *.tss
307 |
308 | # Telerik's JustMock configuration file
309 | *.jmconfig
310 |
311 | # BizTalk build output
312 | *.btp.cs
313 | *.btm.cs
314 | *.odx.cs
315 | *.xsd.cs
316 |
317 | # OpenCover UI analysis results
318 | OpenCover/
319 |
320 | # Azure Stream Analytics local run output
321 | ASALocalRun/
322 |
323 | # MSBuild Binary and Structured Log
324 | *.binlog
325 |
326 | # NVidia Nsight GPU debugger configuration file
327 | *.nvuser
328 |
329 | # MFractors (Xamarin productivity tool) working folder
330 | .mfractor/
331 |
332 | .vscode/
333 | /build/*.exe
334 | /build/*.dll
335 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as
6 | contributors and maintainers pledge to making participation in our project and
7 | our community a harassment-free experience for everyone, regardless of age, body
8 | size, disability, ethnicity, sex characteristics, gender identity and expression,
9 | level of experience, education, socio-economic status, nationality, personal
10 | appearance, race, religion, or sexual identity and orientation.
11 |
12 | ## Our Standards
13 |
14 | Examples of behavior that contributes to creating a positive environment
15 | include:
16 |
17 | * Using welcoming and inclusive language
18 | * Being respectful of differing viewpoints and experiences
19 | * Gracefully accepting constructive criticism
20 | * Focusing on what is best for the community
21 | * Showing empathy towards other community members
22 |
23 | Examples of unacceptable behavior by participants include:
24 |
25 | * The use of sexualized language or imagery and unwelcome sexual attention or
26 | advances
27 | * Trolling, insulting/derogatory comments, and personal or political attacks
28 | * Public or private harassment
29 | * Publishing others' private information, such as a physical or electronic
30 | address, without explicit permission
31 | * Other conduct which could reasonably be considered inappropriate in a
32 | professional setting
33 |
34 | ## Our Responsibilities
35 |
36 | Project maintainers are responsible for clarifying the standards of acceptable
37 | behavior and are expected to take appropriate and fair corrective action in
38 | response to any instances of unacceptable behavior.
39 |
40 | Project maintainers have the right and responsibility to remove, edit, or
41 | reject comments, commits, code, wiki edits, issues, and other contributions
42 | that are not aligned to this Code of Conduct, or to ban temporarily or
43 | permanently any contributor for other behaviors that they deem inappropriate,
44 | threatening, offensive, or harmful.
45 |
46 | ## Scope
47 |
48 | This Code of Conduct applies both within project spaces and in public spaces
49 | when an individual is representing the project or its community. Examples of
50 | representing a project or community include using an official project e-mail
51 | address, posting via an official social media account, or acting as an appointed
52 | representative at an online or offline event. Representation of a project may be
53 | further defined and clarified by project maintainers.
54 |
55 | ## Enforcement
56 |
57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
58 | reported by contacting the project team at drwatson1@yandex.ru . All
59 | complaints will be reviewed and investigated and will result in a response that
60 | is deemed necessary and appropriate to the circumstances. The project team is
61 | obligated to maintain confidentiality with regard to the reporter of an incident.
62 | Further details of specific enforcement policies may be posted separately.
63 |
64 | Project maintainers who do not follow or enforce the Code of Conduct in good
65 | faith may face temporary or permanent repercussions as determined by other
66 | members of the project's leadership.
67 |
68 | ## Attribution
69 |
70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
72 |
73 | [homepage]: https://www.contributor-covenant.org
74 |
75 | For answers to common questions about this code of conduct, see
76 | https://www.contributor-covenant.org/faq
77 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Sergey Tregub
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.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # DbUp Command Line Interface
2 |
3 | [](https://www.nuget.org/packages/dbup-cli)
4 |
5 | This project is inspired and based on [DbUp](https://dbup.readthedocs.io/en/latest/) project. That is how its authors describe their project:
6 |
7 | > DbUp is a .NET library that helps you to deploy changes to SQL Server databases. It tracks which SQL scripts have been run already, and runs the change scripts that are needed to get your database up to date. [from official documentation](https://dbup.readthedocs.io/en/latest/)
8 |
9 | It does exactly that and does it pretty well, except that it supports not only SQL Server, but some other databases too. That is a great project that helps you a lot when you want to deploy database changes to your server, and you are a developer. Because it is merely a library and this is your responsibility to create an executable to run it. Of course, you can use PowerShell, but it is for fans only. Though it is pretty simple, however in every new project you have to create a new executable to deploy changes, and after the fifth project, it becomes a little annoying.
10 |
11 | However, what if you are not a developer, or you are a lazy developer (in a good sense) who doesn't want to do the same thing in every new project? You can use DbUp-CLI that is already do it.
12 |
13 | The tool has almost all the features the DbUp has, but without a single line of code, so I do not list them here, just the features of the tool itself.
14 |
15 | ## Features
16 |
17 | * Almost all of the DbUp features
18 | * Cross-platform (dotnet needed)
19 | * Easy to install - can be installed as a dotnet global tool
20 | * Minimum command line options
21 | * Uses a configuration file to store deploy options, so you can put it along with your SQL scripts under your favorite source control system
22 | * Uses YAML format for a configuration file to improve readability
23 | * Quick start:
24 | * Creates a configuration file with default options for you
25 | * Default configuration is suitable for the most cases, so you should set only a connection string to your database to run the first migration
26 | * The configuration file contains all options with default values and a brief explanation
27 |
28 | ## Documentation
29 |
30 | * [Installation](https://github.com/drwatson1/dbup-cli/wiki/Home#installation)
31 | * [Getting Started](https://github.com/drwatson1/dbup-cli/wiki/Home#getting-started)
32 | * [Supported DB Providers](https://github.com/drwatson1/dbup-cli/Home#supported-db-providers)
33 | * [Configuration File](https://github.com/drwatson1/dbup-cli/wiki/Home#configuration-file)
34 | * [Required Options](https://github.com/drwatson1/dbup-cli/wiki/Home#required-options)
35 | * [Transaction Related Options](https://github.com/drwatson1/dbup-cli/wiki/Home#transaction-related-options)
36 | * [Logging Options](https://github.com/drwatson1/dbup-cli/wiki/Home#logging-options)
37 | * [Script Selection](https://github.com/drwatson1/dbup-cli/wiki/Home#script-selection)
38 | * [Folders](https://github.com/drwatson1/dbup-cli/wiki/Home#folders)
39 | * [Scripts order](https://github.com/drwatson1/dbup-cli/wiki/Home#scripts-order)
40 | * [Filter](https://github.com/drwatson1/dbup-cli/wiki/Home#filter)
41 | * [Always Executed Scripts](https://github.com/drwatson1/dbup-cli/wiki/Home#always-executed-scripts)
42 | * [Encoding](https://github.com/drwatson1/dbup-cli/wiki/Home#encoding)
43 | * [Naming](https://github.com/drwatson1/dbup-cli/wiki#naming)
44 | * [Variables in the Scripts](https://github.com/drwatson1/dbup-cli/wiki/Home#variables-in-the-scripts)
45 | * [Environment Variables](https://github.com/drwatson1/dbup-cli/wiki/Home#environment-variables)
46 | * [Using .env Files](https://github.com/drwatson1/dbup-cli/wiki/Home#using-env-files)
47 | * [Custom journal table name](https://github.com/drwatson1/dbup-cli/wiki/Home#custom-journal-table-name)
48 | * [Command Line Options Reference](https://github.com/drwatson1/dbup-cli/wiki/Command-Line-Options)
49 | * [Original DbUp Documentation](https://dbup.readthedocs.io/en/latest/)
50 |
51 | ## Supported Databases
52 |
53 | * MS SQL Server
54 | * AzureSQL
55 | * PostgreSQL
56 | * MySQL
57 | * CockroachDB (by @lbguilherme)
58 |
59 | ## Release Notes
60 |
61 | |Date|Version|Description|
62 | |-|-|-|
63 | |2023-06-12|1.8.1|Improve error reporting
64 | |2023-01-18|1.8.0|Add support of .Net 7.0
65 | |2022-06-11|1.7.0|Add support of CockroachDB, thanks to @lbguilherme
66 | |2022-05-10|1.6.6|Add support of .Net 6
67 | |2022-02-14|1.6.5|Support of DisableVars
68 | |2022-02-06|1.6.4|Support of drop and ensure for Azure SQL
69 | |2022-02-02|1.6.3|Support of AzureSQL integrated security
70 | |2022-01-30|1.6.2|PostgreSQL SCRAM authentication support interim fix
71 | |2022-01-29|1.6.1|BUGFIX: 'version' and '--version' should return exit code 0
72 | |2021-10-03|1.6.0|Add a 'journalTo' option to dbup.yml
73 | |2021-03-28|1.5.0|Add support of .Net Core 3.1 and .Net 5.0
74 | |2021-03-27|1.4.0|Add script naming options
Load .env.local after .env
75 | |2020-05-30|1.3.0|Support of MySQL, improve stability of integration tests
76 | |2020-03-20|1.2.0|Add a connectionTimeoutSec option
77 | |2019-08-27|1.1.2|Minor fixes
78 | |2019-04-11|1.1.0|PostgreSQL support
79 | |2019-03-25|1.0.1|Initial version (DbUp 4.2)
80 |
--------------------------------------------------------------------------------
/build/PackDbUp.cmd:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 |
3 | SET BINDIR=..\src\dbup-cli\bin\Release\net462
4 |
5 | ILMerge.exe %BINDIR%\dbup-cli.exe /ndebug /out:dbup-cli.exe ^
6 | %BINDIR%\CommandLine.dll ^
7 | %BINDIR%\dbup-core.dll ^
8 | %BINDIR%\dbup-mysql.dll ^
9 | %BINDIR%\dbup-postgresql.dll ^
10 | %BINDIR%\dbup-sqlserver.dll ^
11 | %BINDIR%\dbup-cockroachdb.dll ^
12 | %BINDIR%\DotNetEnv.dll ^
13 | %BINDIR%\Microsoft.Azure.Services.AppAuthentication.dll ^
14 | %BINDIR%\Microsoft.IdentityModel.Clients.ActiveDirectory.dll ^
15 | %BINDIR%\Microsoft.Win32.Primitives.dll ^
16 | %BINDIR%\MySql.Data.dll ^
17 | %BINDIR%\Npgsql.dll ^
18 | %BINDIR%\Optional.dll ^
19 | %BINDIR%\Sprache.dll ^
20 | %BINDIR%\System.AppContext.dll ^
21 | %BINDIR%\System.Console.dll ^
22 | %BINDIR%\System.Diagnostics.DiagnosticSource.dll ^
23 | %BINDIR%\System.Diagnostics.Tracing.dll ^
24 | %BINDIR%\System.Globalization.Calendars.dll ^
25 | %BINDIR%\System.IO.Compression.dll ^
26 | %BINDIR%\System.IO.Compression.ZipFile.dll ^
27 | %BINDIR%\System.IO.dll ^
28 | %BINDIR%\System.IO.FileSystem.dll ^
29 | %BINDIR%\System.IO.FileSystem.Primitives.dll ^
30 | %BINDIR%\System.Net.Http.dll ^
31 | %BINDIR%\System.Net.Sockets.dll ^
32 | %BINDIR%\System.Reflection.dll ^
33 | %BINDIR%\System.Runtime.CompilerServices.Unsafe.dll ^
34 | %BINDIR%\System.Runtime.dll ^
35 | %BINDIR%\System.Runtime.Extensions.dll ^
36 | %BINDIR%\System.Runtime.InteropServices.dll ^
37 | %BINDIR%\System.Runtime.InteropServices.RuntimeInformation.dll ^
38 | %BINDIR%\System.Security.Cryptography.Algorithms.dll ^
39 | %BINDIR%\System.Security.Cryptography.Encoding.dll ^
40 | %BINDIR%\System.Security.Cryptography.Primitives.dll ^
41 | %BINDIR%\System.Security.Cryptography.X509Certificates.dll ^
42 | %BINDIR%\System.Text.Encoding.CodePages.dll ^
43 | %BINDIR%\System.Threading.Tasks.Extensions.dll ^
44 | %BINDIR%\System.Xml.ReaderWriter.dll ^
45 | %BINDIR%\YamlDotNet.dll
46 |
--------------------------------------------------------------------------------
/build/README.md:
--------------------------------------------------------------------------------
1 |
2 | ## Pack the .NET Framework executable into one exe file
3 |
4 | You will need `ILMerge.exe` and `System.Compiler.dll` in this directory.
5 | Download them [here](https://www.nuget.org/packages/ilmerge/) and unpack from `tools\net452`.
6 |
7 | Then, run `PackDbUp.cmd` and you get a single self-contained `dbup-cli.exe`.
8 |
9 | Note that the script may need upgrading after a code change
10 | as the list of the dependent dlls is hardcoded in the script.
11 |
--------------------------------------------------------------------------------
/src/dbup-cli.integration-tests/CockroachDbTests.cs:
--------------------------------------------------------------------------------
1 | using DbUp.Cli.Tests.TestInfrastructure;
2 | using Microsoft.VisualStudio.TestTools.UnitTesting;
3 | using System;
4 | using System.IO;
5 | using System.Reflection;
6 | using FluentAssertions;
7 | using System.Data.SqlClient;
8 | using System.Collections.Generic;
9 | using System.Threading.Tasks;
10 | using Npgsql;
11 | using System.Data.Common;
12 |
13 | namespace DbUp.Cli.IntegrationTests
14 | {
15 | [TestClass]
16 | public class CocroachDbTests : DockerBasedTest
17 | {
18 | readonly CaptureLogsLogger Logger;
19 | readonly IEnvironment Env;
20 |
21 | public CocroachDbTests()
22 | {
23 | Env = new CliEnvironment();
24 | Logger = new CaptureLogsLogger();
25 |
26 | Environment.SetEnvironmentVariable("CONNSTR", "Host=127.0.0.1;Port=26257;SSL Mode=Disable;Database=dbup;Username=root");
27 | }
28 |
29 | string GetBasePath(string subPath = "EmptyScript") =>
30 | Path.Combine(Assembly.GetExecutingAssembly().Location, $@"..\Scripts\CockroachDb\{subPath}");
31 |
32 | string GetConfigPath(string name = "dbup.yml", string subPath = "EmptyScript") => new DirectoryInfo(Path.Combine(GetBasePath(subPath), name)).FullName;
33 |
34 | Func CreateConnection = () => new NpgsqlConnection("Host=127.0.0.1;Port=26257;SSL Mode=Disable;Database=defaultdb;Username=root");
35 |
36 | [TestInitialize]
37 | public Task TestInitialize()
38 | {
39 | /*
40 | * Before the first run, download the image:
41 | * docker pull cockroachdb/cockroach:v22.1.1
42 | * */
43 | return DockerInitialize(
44 | "cockroachdb/cockroach:v22.1.1",
45 | new List() { },
46 | new List() { "start-single-node", "--insecure" },
47 | "26257",
48 | CreateConnection
49 | );
50 | }
51 |
52 | [TestCleanup]
53 | public Task TestCleanup()
54 | {
55 | return DockerCleanup(CreateConnection, con => new NpgsqlCommand("select count(*) from SchemaVersions where scriptname = '001.sql'", con as NpgsqlConnection));
56 | }
57 |
58 | [TestMethod]
59 | public void Ensure_CreateANewDb()
60 | {
61 | var engine = new ToolEngine(Env, Logger);
62 |
63 | var result = engine.Run("upgrade", "--ensure", GetConfigPath());
64 | result.Should().Be(0);
65 |
66 | using (var connection = new NpgsqlConnection(Environment.GetEnvironmentVariable("CONNSTR")))
67 | using (var command = new NpgsqlCommand("select count(*) from SchemaVersions where scriptname = '001.sql'", connection))
68 | {
69 | connection.Open();
70 | var count = command.ExecuteScalar();
71 |
72 | count.Should().Be(1);
73 | }
74 | }
75 |
76 | /*
77 | // Drop database does not supported for PostgreSQL by DbUp
78 | [TestMethod]
79 | public void Drop_DropADb()
80 | {
81 | var engine = new ToolEngine(Env, Logger);
82 |
83 | engine.Run("upgrade", "--ensure", GetConfigPath());
84 | var result = engine.Run("drop", GetConfigPath());
85 | result.Should().Be(0);
86 | using (var connection = new NpgsqlConnection(Environment.GetEnvironmentVariable("CONNSTR")))
87 | using (var command = new NpgsqlCommand("select count(*) from SchemaVersions where scriptname = '001.sql'", connection))
88 | {
89 | Action a = () => connection.Open();
90 | a.Should().Throw("Database DbUp should not exist");
91 | }
92 | }
93 | */
94 |
95 | [TestMethod]
96 | public void DatabaseShouldNotExistBeforeTestRun()
97 | {
98 | using (var connection = new NpgsqlConnection(Environment.GetEnvironmentVariable("CONNSTR")))
99 | using (var command = new NpgsqlCommand("select count(*) from SchemaVersions where scriptname = '001.sql'", connection))
100 | {
101 | Action a = () => { connection.Open(); command.ExecuteScalar(); };
102 | a.Should().Throw("Database DbUp should not exist");
103 | }
104 | }
105 |
106 | [TestMethod]
107 | public void UpgradeCommand_ShouldUseConnectionTimeoutForLongrunningQueries()
108 | {
109 | var engine = new ToolEngine(Env, Logger);
110 |
111 | var r = engine.Run("upgrade", "--ensure", GetConfigPath("dbup.yml", "Timeout"));
112 | r.Should().Be(1);
113 | }
114 |
115 | [TestMethod]
116 | public void UpgradeCommand_ShouldUseASpecifiedJournal()
117 | {
118 | var engine = new ToolEngine(Env, Logger);
119 |
120 | var result = engine.Run("upgrade", "--ensure", GetConfigPath("dbup.yml", "JournalTableScript"));
121 | result.Should().Be(0);
122 |
123 | using (var connection = new NpgsqlConnection(Environment.GetEnvironmentVariable("CONNSTR")))
124 | using (var command = new NpgsqlCommand("select count(*) from public.journal where scriptname = '001.sql'", connection))
125 | {
126 | connection.Open();
127 | var count = command.ExecuteScalar();
128 |
129 | count.Should().Be(1);
130 | }
131 | }
132 |
133 | }
134 | }
135 |
--------------------------------------------------------------------------------
/src/dbup-cli.integration-tests/DockerBasedTest.cs:
--------------------------------------------------------------------------------
1 | using Docker.DotNet;
2 | using Docker.DotNet.Models;
3 | using FakeItEasy;
4 | using FluentAssertions;
5 | using Microsoft.VisualStudio.TestTools.UnitTesting;
6 | using System;
7 | using System.Collections.Generic;
8 | using System.Data.Common;
9 | using System.Threading.Tasks;
10 |
11 | namespace DbUp.Cli.IntegrationTests
12 | {
13 | public class DockerBasedTest
14 | {
15 | private const string DockerEngineUri = "npipe://./pipe/docker_engine";
16 | private const string HostIp = "127.0.0.1";
17 |
18 | DockerClient DockerClient;
19 | string ContainerId;
20 |
21 | protected Task DockerInitialize(string imageName, List environmentVariables, string port, Func createConnection)
22 | {
23 | return DockerInitialize(imageName, environmentVariables, new List(), port, createConnection);
24 | }
25 |
26 | protected async Task DockerInitialize(string imageName, List environmentVariables, List cmd, string port, Func createConnection)
27 | {
28 | DockerClient = new DockerClientConfiguration(new Uri(DockerEngineUri)).CreateClient();
29 | var pars = new CreateContainerParameters(new Config()
30 | {
31 | Image = imageName,
32 | ExposedPorts = new Dictionary()
33 | {
34 | { port, new EmptyStruct() }
35 | },
36 | Env = environmentVariables,
37 | NetworkDisabled = false,
38 | Cmd = cmd
39 | });
40 |
41 | pars.HostConfig = new HostConfig()
42 | {
43 | AutoRemove = true,
44 | PortBindings = new Dictionary>()
45 | {
46 | { port, new List { new PortBinding() { HostPort = port, HostIP = HostIp } } }
47 | }
48 | };
49 |
50 | try
51 | {
52 | await DockerClient.Images.CreateImageAsync(
53 | new ImagesCreateParameters
54 | {
55 | FromImage = imageName
56 | },
57 | null, A.Fake>());
58 |
59 | var cont = await DockerClient.Containers.CreateContainerAsync(pars);
60 | ContainerId = cont.ID;
61 | var res = await DockerClient.Containers.StartContainerAsync(ContainerId, new ContainerStartParameters());
62 | res.Should().BeTrue();
63 | }
64 | catch (Exception ex)
65 | {
66 | Assert.Fail(ex.Message);
67 | }
68 |
69 | var started = DateTime.Now;
70 | var connected = false;
71 | while (DateTime.Now - started < TimeSpan.FromMinutes(1))
72 | {
73 | using (var connection = createConnection())
74 | {
75 | try
76 | {
77 | connection.Open();
78 | connected = true;
79 | break;
80 | }
81 | catch
82 | {
83 | await Task.Delay(1000);
84 | continue;
85 | }
86 | }
87 | }
88 |
89 | connected.Should().BeTrue("Server should be awailable to connect");
90 | }
91 |
92 | protected async Task DockerCleanup(Func createConnection, Func createCommand)
93 | {
94 | await DockerClient.Containers.StopContainerAsync(ContainerId, new ContainerStopParameters() { WaitBeforeKillSeconds = 1 });
95 |
96 | var started = DateTime.Now;
97 | while (DateTime.Now - started < TimeSpan.FromMinutes(2))
98 | {
99 | using (var connection = createConnection())
100 | using (var command = createCommand(connection))
101 | {
102 | try
103 | {
104 | await connection.OpenAsync();
105 | await command.ExecuteScalarAsync();
106 | await Task.Delay(1000);
107 | }
108 | catch
109 | {
110 | await Task.Delay(1000);
111 | return;
112 | }
113 | }
114 | }
115 | }
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/src/dbup-cli.integration-tests/MySqlTests.cs:
--------------------------------------------------------------------------------
1 | using DbUp.Cli.Tests.TestInfrastructure;
2 | using Microsoft.VisualStudio.TestTools.UnitTesting;
3 | using System;
4 | using System.IO;
5 | using System.Reflection;
6 | using FluentAssertions;
7 | using System.Data.SqlClient;
8 | using System.Collections.Generic;
9 | using System.Threading.Tasks;
10 | using System.Data.Common;
11 | using MySql;
12 | using MySql.Data.MySqlClient;
13 |
14 | namespace DbUp.Cli.IntegrationTests
15 | {
16 | [TestClass]
17 | public class MySqlTests : DockerBasedTest
18 | {
19 | readonly CaptureLogsLogger Logger;
20 | readonly IEnvironment Env;
21 |
22 | readonly static string Pwd = "MyPwd2020";
23 | readonly static string DbName = "DbUp";
24 |
25 | public MySqlTests()
26 | {
27 | Env = new CliEnvironment();
28 | Logger = new CaptureLogsLogger();
29 |
30 | Environment.SetEnvironmentVariable("CONNSTR", $"Server=127.0.0.1;Database={DbName};Uid=root;Pwd={Pwd};");
31 | }
32 |
33 | string GetBasePath(string subPath = "EmptyScript")
34 | => Path.Combine(Assembly.GetExecutingAssembly().Location, $@"..\Scripts\MySQL\{subPath}");
35 |
36 | string GetConfigPath(string name = "dbup.yml", string subPath = "EmptyScript")
37 | => new DirectoryInfo(Path.Combine(GetBasePath(subPath), name)).FullName;
38 |
39 | Func CreateConnection = ()
40 | => new MySqlConnection($"Server=127.0.0.1;Uid=root;Pwd={Pwd};");
41 |
42 | [TestInitialize]
43 | public async Task TestInitialize()
44 | {
45 | /*
46 | * Before the first run, download the image:
47 | * docker pull mysql:8.0.20
48 | * */
49 |
50 | await DockerInitialize(
51 | "mysql:8.0.20",
52 | new List()
53 | {
54 | $"MYSQL_ROOT_PASSWORD={Pwd}"
55 | },
56 | "3306",
57 | CreateConnection
58 | );
59 | }
60 |
61 | [TestCleanup]
62 | public async Task TestCleanup()
63 | {
64 | await DockerCleanup(CreateConnection, con => new MySqlCommand("select count(*) from schemaversions where scriptname = '001.sql'", con as MySqlConnection));
65 | }
66 |
67 | [TestMethod]
68 | public void Ensure_CreateANewDb()
69 | {
70 | var engine = new ToolEngine(Env, Logger);
71 |
72 | var result = engine.Run("upgrade", "--ensure", GetConfigPath());
73 | result.Should().Be(0);
74 |
75 | using (var connection = new MySqlConnection(Environment.GetEnvironmentVariable("CONNSTR")))
76 | using (var command = new MySqlCommand("select count(*) from schemaversions where scriptname = '001.sql'", connection))
77 | {
78 | connection.Open();
79 | var count = command.ExecuteScalar();
80 |
81 | count.Should().Be(1);
82 | }
83 | }
84 |
85 | /*
86 | * // Don't supported
87 | [TestMethod]
88 | public void Drop_DropADb()
89 | {
90 | var engine = new ToolEngine(Env, Logger);
91 |
92 | engine.Run("upgrade", "--ensure", GetConfigPath());
93 | var result = engine.Run("drop", GetConfigPath());
94 | result.Should().Be(0);
95 | using (var connection = new MySqlConnection(Environment.GetEnvironmentVariable("CONNSTR")))
96 | using (var command = new MySqlCommand("select count(*) from schemaversions where scriptname = '001.sql'", connection))
97 | {
98 | Action a = () => connection.Open();
99 | a.Should().Throw($"Database {DbName} should not exist");
100 | }
101 | }
102 | */
103 |
104 | [TestMethod]
105 | public void DatabaseShouldNotExistBeforeTestRun()
106 | {
107 | using (var connection = new MySqlConnection(Environment.GetEnvironmentVariable("CONNSTR")))
108 | using (var command = new MySqlCommand("select count(*) from schemaversions where scriptname = '001.sql'", connection))
109 | {
110 | Action a = () => connection.Open();
111 | a.Should().Throw($"Database {DbName} should not exist");
112 | }
113 | }
114 |
115 | [TestMethod]
116 | public void UpgradeCommand_ShouldUseConnectionTimeoutForLongrunningQueries()
117 | {
118 | var engine = new ToolEngine(Env, Logger);
119 |
120 | var r = engine.Run("upgrade", "--ensure", GetConfigPath("dbup.yml", "Timeout"));
121 | r.Should().Be(1);
122 | }
123 |
124 | [TestMethod]
125 | public void UpgradeCommand_ShouldUseASpecifiedJournal()
126 | {
127 | var engine = new ToolEngine(Env, Logger);
128 |
129 | var result = engine.Run("upgrade", "--ensure", GetConfigPath("dbup.yml", "JournalTableScript"));
130 | result.Should().Be(0);
131 |
132 | using (var connection = new MySqlConnection(Environment.GetEnvironmentVariable("CONNSTR")))
133 | using (var command = new MySqlCommand("select count(*) from DbUp.testTable where scriptname = '001.sql'", connection))
134 | {
135 | connection.Open();
136 | var count = command.ExecuteScalar();
137 |
138 | count.Should().Be(1);
139 | }
140 | }
141 | }
142 | }
143 |
--------------------------------------------------------------------------------
/src/dbup-cli.integration-tests/PostgreSqlTests.cs:
--------------------------------------------------------------------------------
1 | using DbUp.Cli.Tests.TestInfrastructure;
2 | using Microsoft.VisualStudio.TestTools.UnitTesting;
3 | using System;
4 | using System.IO;
5 | using System.Reflection;
6 | using FluentAssertions;
7 | using System.Data.SqlClient;
8 | using System.Collections.Generic;
9 | using System.Threading.Tasks;
10 | using Npgsql;
11 | using System.Data.Common;
12 |
13 | namespace DbUp.Cli.IntegrationTests
14 | {
15 | [TestClass]
16 | public class PostgreSqlTests : DockerBasedTest
17 | {
18 | readonly CaptureLogsLogger Logger;
19 | readonly IEnvironment Env;
20 |
21 | public PostgreSqlTests()
22 | {
23 | Env = new CliEnvironment();
24 | Logger = new CaptureLogsLogger();
25 |
26 | Environment.SetEnvironmentVariable("CONNSTR", "Host=127.0.0.1;Database=dbup;Username=postgres;Password=PostgresPwd2019;Port=5432;Timeout=60;CommandTimeout=60");
27 | }
28 |
29 | string GetBasePath(string subPath = "EmptyScript") =>
30 | Path.Combine(Assembly.GetExecutingAssembly().Location, $@"..\Scripts\PostgreSql\{subPath}");
31 |
32 | string GetConfigPath(string name = "dbup.yml", string subPath = "EmptyScript") => new DirectoryInfo(Path.Combine(GetBasePath(subPath), name)).FullName;
33 |
34 | Func CreateConnection = () => new NpgsqlConnection("Host=127.0.0.1;Database=postgres;Username=postgres;Password=PostgresPwd2019;Port=5432;Timeout=60;CommandTimeout=60");
35 |
36 | [TestInitialize]
37 | public Task TestInitialize()
38 | {
39 | /*
40 | * Before the first run, download the image:
41 | * docker pull postgres:11.2
42 | * */
43 |
44 | return DockerInitialize(
45 | "postgres:11.2",
46 | new List()
47 | {
48 | "POSTGRES_PASSWORD=PostgresPwd2019"
49 | },
50 | "5432",
51 | CreateConnection
52 | );
53 | }
54 |
55 | [TestCleanup]
56 | public Task TestCleanup()
57 | {
58 | return DockerCleanup(CreateConnection, con => new NpgsqlCommand("select count(*) from SchemaVersions where scriptname = '001.sql'", con as NpgsqlConnection));
59 | }
60 |
61 | [TestMethod]
62 | public void Ensure_CreateANewDb()
63 | {
64 | var engine = new ToolEngine(Env, Logger);
65 |
66 | var result = engine.Run("upgrade", "--ensure", GetConfigPath());
67 | result.Should().Be(0);
68 |
69 | using (var connection = new NpgsqlConnection(Environment.GetEnvironmentVariable("CONNSTR")))
70 | using (var command = new NpgsqlCommand("select count(*) from SchemaVersions where scriptname = '001.sql'", connection))
71 | {
72 | connection.Open();
73 | var count = command.ExecuteScalar();
74 |
75 | count.Should().Be(1);
76 | }
77 | }
78 |
79 | /*
80 | // Drop database does not supported for PostgreSQL by DbUp
81 | [TestMethod]
82 | public void Drop_DropADb()
83 | {
84 | var engine = new ToolEngine(Env, Logger);
85 |
86 | engine.Run("upgrade", "--ensure", GetConfigPath());
87 | var result = engine.Run("drop", GetConfigPath());
88 | result.Should().Be(0);
89 | using (var connection = new NpgsqlConnection(Environment.GetEnvironmentVariable("CONNSTR")))
90 | using (var command = new NpgsqlCommand("select count(*) from SchemaVersions where scriptname = '001.sql'", connection))
91 | {
92 | Action a = () => connection.Open();
93 | a.Should().Throw("Database DbUp should not exist");
94 | }
95 | }
96 | */
97 |
98 | [TestMethod]
99 | public void DatabaseShouldNotExistBeforeTestRun()
100 | {
101 | using (var connection = new NpgsqlConnection(Environment.GetEnvironmentVariable("CONNSTR")))
102 | using (var command = new NpgsqlCommand("select count(*) from SchemaVersions where scriptname = '001.sql'", connection))
103 | {
104 | Action a = () => { connection.Open(); command.ExecuteScalar(); };
105 | a.Should().Throw("Database DbUp should not exist");
106 | }
107 | }
108 |
109 | [TestMethod]
110 | public void UpgradeCommand_ShouldUseConnectionTimeoutForLongrunningQueries()
111 | {
112 | var engine = new ToolEngine(Env, Logger);
113 |
114 | var r = engine.Run("upgrade", "--ensure", GetConfigPath("dbup.yml", "Timeout"));
115 | r.Should().Be(1);
116 | }
117 |
118 | [TestMethod]
119 | public void UpgradeCommand_ShouldUseASpecifiedJournal()
120 | {
121 | var engine = new ToolEngine(Env, Logger);
122 |
123 | var result = engine.Run("upgrade", "--ensure", GetConfigPath("dbup.yml", "JournalTableScript"));
124 | result.Should().Be(0);
125 |
126 | using (var connection = new NpgsqlConnection(Environment.GetEnvironmentVariable("CONNSTR")))
127 | using (var command = new NpgsqlCommand("select count(*) from public.journal where scriptname = '001.sql'", connection))
128 | {
129 | connection.Open();
130 | var count = command.ExecuteScalar();
131 |
132 | count.Should().Be(1);
133 | }
134 | }
135 |
136 | }
137 | }
138 |
--------------------------------------------------------------------------------
/src/dbup-cli.integration-tests/README.md:
--------------------------------------------------------------------------------
1 | # Integration tests
2 |
3 | These integration tests are intended to ensure that the tool can interact with the real databases. Technically, it uses the Docker engine to run Databases, so you should install the Docker first. On Windows, I recommend using the Docker Desktop over the WSL 2. You can find a manual in the [Docker Docuntation](https://docs.docker.com/docker-for-windows/wsl/).
4 |
5 | Each test creates and runs a container with a database engine, then runs test, stops and remove the container. So, before running a test, you should download a container manually. For example:
6 |
7 | ```
8 | docker pull mcr.microsoft.com/mssql/server:2017-CU12-ubuntu
9 | ```
10 |
11 | You can find an appropriate command in the corresponding test code.
12 |
--------------------------------------------------------------------------------
/src/dbup-cli.integration-tests/Scripts/CockroachDb/EmptyScript/001.sql:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/dbup-cli.integration-tests/Scripts/CockroachDb/EmptyScript/dbup.yml:
--------------------------------------------------------------------------------
1 | dbUp:
2 | version: 1 # should be 1
3 | provider: CockroachDb # DB provider: sqlserver
4 | connectionString: $CONNSTR$ # Connection string to DB. For example, "Data Source=(localdb)\dbup;Initial Catalog=MyDb;Integrated Security=True" for sqlserver
5 |
--------------------------------------------------------------------------------
/src/dbup-cli.integration-tests/Scripts/CockroachDb/JournalTableScript/001.sql:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/dbup-cli.integration-tests/Scripts/CockroachDb/JournalTableScript/dbup.yml:
--------------------------------------------------------------------------------
1 | dbUp:
2 | version: 1 # should be 1
3 | provider: CockroachDb # DB provider: sqlserver
4 | connectionString: $CONNSTR$ # Connection string to DB. For example, "Data Source=(localdb)\dbup;Initial Catalog=MyDb;Integrated Security=True" for sqlserver
5 | connectionTimeoutSec: 60
6 | journalTo:
7 | schema: public
8 | table: journal
9 |
--------------------------------------------------------------------------------
/src/dbup-cli.integration-tests/Scripts/CockroachDb/Timeout/001.sql:
--------------------------------------------------------------------------------
1 | SELECT pg_sleep(60);
2 |
--------------------------------------------------------------------------------
/src/dbup-cli.integration-tests/Scripts/CockroachDb/Timeout/dbup.yml:
--------------------------------------------------------------------------------
1 | dbUp:
2 | version: 1 # should be 1
3 | provider: CockroachDb # DB provider: sqlserver
4 | connectionString: $CONNSTR$ # Connection string to DB. For example, "Data Source=(localdb)\dbup;Initial Catalog=MyDb;Integrated Security=True" for sqlserver
5 | connectionTimeoutSec: 10 # Connection timeout in seconds
6 |
--------------------------------------------------------------------------------
/src/dbup-cli.integration-tests/Scripts/MySql/EmptyScript/001.sql:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/dbup-cli.integration-tests/Scripts/MySql/EmptyScript/dbup.yml:
--------------------------------------------------------------------------------
1 | dbUp:
2 | version: 1 # should be 1
3 | provider: mysql # DB provider: sqlserver
4 | connectionString: $CONNSTR$ # Connection string to DB. For example, "Data Source=(localdb)\dbup;Initial Catalog=MyDb;Integrated Security=True" for sqlserver
5 |
--------------------------------------------------------------------------------
/src/dbup-cli.integration-tests/Scripts/MySql/JournalTableScript/001.sql:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/dbup-cli.integration-tests/Scripts/MySql/JournalTableScript/dbup.yml:
--------------------------------------------------------------------------------
1 | dbUp:
2 | version: 1 # should be 1
3 | provider: mysql # DB provider: sqlserver
4 | connectionString: $CONNSTR$ # Connection string to DB. For example, "Data Source=(localdb)\dbup;Initial Catalog=MyDb;Integrated Security=True" for sqlserver
5 | journalTo:
6 | schema: "DbUp"
7 | table: "testTable"
--------------------------------------------------------------------------------
/src/dbup-cli.integration-tests/Scripts/MySql/Timeout/001.sql:
--------------------------------------------------------------------------------
1 | SELECT NOW() 'BEFORE WAIT';
2 | SELECT SLEEP (60);
3 | SELECT NOW() 'AFTER WAIT';
4 |
--------------------------------------------------------------------------------
/src/dbup-cli.integration-tests/Scripts/MySql/Timeout/dbup.yml:
--------------------------------------------------------------------------------
1 | dbUp:
2 | version: 1 # should be 1
3 | provider: mysql # DB provider: sqlserver
4 | connectionString: $CONNSTR$ # Connection string to DB. For example, "Data Source=(localdb)\dbup;Initial Catalog=MyDb;Integrated Security=True" for sqlserver
5 | connectionTimeoutSec: 10 # Connection timeout in seconds
--------------------------------------------------------------------------------
/src/dbup-cli.integration-tests/Scripts/PostgreSql/EmptyScript/001.sql:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/dbup-cli.integration-tests/Scripts/PostgreSql/EmptyScript/dbup.yml:
--------------------------------------------------------------------------------
1 | dbUp:
2 | version: 1 # should be 1
3 | provider: postgresql # DB provider: sqlserver
4 | connectionString: $CONNSTR$ # Connection string to DB. For example, "Data Source=(localdb)\dbup;Initial Catalog=MyDb;Integrated Security=True" for sqlserver
5 |
--------------------------------------------------------------------------------
/src/dbup-cli.integration-tests/Scripts/PostgreSql/JournalTableScript/001.sql:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/dbup-cli.integration-tests/Scripts/PostgreSql/JournalTableScript/dbup.yml:
--------------------------------------------------------------------------------
1 | dbUp:
2 | version: 1 # should be 1
3 | provider: postgresql # DB provider: sqlserver
4 | connectionString: $CONNSTR$ # Connection string to DB. For example, "Data Source=(localdb)\dbup;Initial Catalog=MyDb;Integrated Security=True" for sqlserver
5 | connectionTimeoutSec: 60
6 | journalTo:
7 | schema: public
8 | table: journal
9 |
--------------------------------------------------------------------------------
/src/dbup-cli.integration-tests/Scripts/PostgreSql/Timeout/001.sql:
--------------------------------------------------------------------------------
1 | SELECT pg_sleep(60);
2 |
--------------------------------------------------------------------------------
/src/dbup-cli.integration-tests/Scripts/PostgreSql/Timeout/dbup.yml:
--------------------------------------------------------------------------------
1 | dbUp:
2 | version: 1 # should be 1
3 | provider: postgresql # DB provider: sqlserver
4 | connectionString: $CONNSTR$ # Connection string to DB. For example, "Data Source=(localdb)\dbup;Initial Catalog=MyDb;Integrated Security=True" for sqlserver
5 | connectionTimeoutSec: 10 # Connection timeout in seconds
6 |
--------------------------------------------------------------------------------
/src/dbup-cli.integration-tests/Scripts/SqlServer/EmptyScript/001.sql:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/dbup-cli.integration-tests/Scripts/SqlServer/EmptyScript/dbup.yml:
--------------------------------------------------------------------------------
1 | dbUp:
2 | version: 1 # should be 1
3 | provider: sqlserver # DB provider: sqlserver
4 | connectionString: $CONNSTR$ # Connection string to DB. For example, "Data Source=(localdb)\dbup;Initial Catalog=MyDb;Integrated Security=True" for sqlserver
5 |
--------------------------------------------------------------------------------
/src/dbup-cli.integration-tests/Scripts/SqlServer/JournalTableScript/001.sql:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/dbup-cli.integration-tests/Scripts/SqlServer/JournalTableScript/dbup.yml:
--------------------------------------------------------------------------------
1 | dbUp:
2 | version: 1 # should be 1
3 | provider: sqlserver # DB provider: sqlserver
4 | connectionString: $CONNSTR$ # Connection string to DB. For example, "Data Source=(localdb)\dbup;Initial Catalog=MyDb;Integrated Security=True" for sqlserver
5 | journalTo:
6 | schema: "dbo"
7 | table: "testTable"
8 |
--------------------------------------------------------------------------------
/src/dbup-cli.integration-tests/Scripts/SqlServer/Timeout/001.sql:
--------------------------------------------------------------------------------
1 | SELECT GETDATE() 'BEFORE WAIT'
2 | WAITFOR DELAY '00:01:00.000'
3 | SELECT GETDATE() 'AFTER WAIT'
--------------------------------------------------------------------------------
/src/dbup-cli.integration-tests/Scripts/SqlServer/Timeout/dbup.yml:
--------------------------------------------------------------------------------
1 | dbUp:
2 | version: 1 # should be 1
3 | provider: sqlserver # DB provider: sqlserver
4 | connectionString: $CONNSTR$ # Connection string to DB. For example, "Data Source=(localdb)\dbup;Initial Catalog=MyDb;Integrated Security=True" for sqlserver
5 | connectionTimeoutSec: 10 # Connection timeout in seconds
--------------------------------------------------------------------------------
/src/dbup-cli.integration-tests/SqlServerTests.cs:
--------------------------------------------------------------------------------
1 | using DbUp.Cli.Tests.TestInfrastructure;
2 | using Microsoft.VisualStudio.TestTools.UnitTesting;
3 | using System;
4 | using System.IO;
5 | using System.Reflection;
6 | using FluentAssertions;
7 | using System.Data.SqlClient;
8 | using System.Collections.Generic;
9 | using System.Threading.Tasks;
10 | using System.Data.Common;
11 |
12 | namespace DbUp.Cli.IntegrationTests
13 | {
14 | [TestClass]
15 | public class SqlServerTests : DockerBasedTest
16 | {
17 | readonly CaptureLogsLogger Logger;
18 | readonly IEnvironment Env;
19 |
20 | public SqlServerTests()
21 | {
22 | Env = new CliEnvironment();
23 | Logger = new CaptureLogsLogger();
24 |
25 | Environment.SetEnvironmentVariable("CONNSTR", "Data Source=127.0.0.1;Initial Catalog=DbUp;Persist Security Info=True;User ID=sa;Password=SaPwd2017");
26 | }
27 |
28 | string GetBasePath(string subPath = "EmptyScript")
29 | => Path.Combine(Assembly.GetExecutingAssembly().Location, $@"..\Scripts\SqlServer\{subPath}");
30 |
31 | string GetConfigPath(string name = "dbup.yml", string subPath = "EmptyScript")
32 | => new DirectoryInfo(Path.Combine(GetBasePath(subPath), name)).FullName;
33 |
34 | Func CreateConnection = ()
35 | => new SqlConnection("Data Source=127.0.0.1;Persist Security Info=True;User ID=sa;Password=SaPwd2017");
36 |
37 | [TestInitialize]
38 | public async Task TestInitialize()
39 | {
40 | /*
41 | * Before the first run, download the image:
42 | * docker pull mcr.microsoft.com/mssql/server:2017-CU12-ubuntu
43 | * */
44 |
45 | await DockerInitialize(
46 | "mcr.microsoft.com/mssql/server:2017-CU12-ubuntu",
47 | new List()
48 | {
49 | "ACCEPT_EULA=Y",
50 | "SA_PASSWORD=SaPwd2017"
51 | },
52 | "1433",
53 | CreateConnection
54 | );
55 | }
56 |
57 | [TestCleanup]
58 | public async Task TestCleanup()
59 | {
60 | await DockerCleanup(CreateConnection, con => new SqlCommand("select count(*) from SchemaVersions where scriptname = '001.sql'", con as SqlConnection));
61 | }
62 |
63 | [TestMethod]
64 | public void Ensure_CreateANewDb()
65 | {
66 | var engine = new ToolEngine(Env, Logger);
67 |
68 | var result = engine.Run("upgrade", "--ensure", GetConfigPath());
69 | result.Should().Be(0);
70 |
71 | using (var connection = new SqlConnection(Environment.GetEnvironmentVariable("CONNSTR")))
72 | using (var command = new SqlCommand("select count(*) from SchemaVersions where scriptname = '001.sql'", connection))
73 | {
74 | connection.Open();
75 | var count = command.ExecuteScalar();
76 |
77 | count.Should().Be(1);
78 | }
79 | }
80 |
81 | [TestMethod]
82 | public void Drop_DropADb()
83 | {
84 | var engine = new ToolEngine(Env, Logger);
85 |
86 | engine.Run("upgrade", "--ensure", GetConfigPath());
87 | var result = engine.Run("drop", GetConfigPath());
88 | result.Should().Be(0);
89 | using (var connection = new SqlConnection(Environment.GetEnvironmentVariable("CONNSTR")))
90 | using (var command = new SqlCommand("select count(*) from SchemaVersions where scriptname = '001.sql'", connection))
91 | {
92 | Action a = () => connection.Open();
93 | a.Should().Throw("Database DbUp should not exist");
94 | }
95 | }
96 |
97 | [TestMethod]
98 | public void DatabaseShouldNotExistBeforeTestRun()
99 | {
100 | using (var connection = new SqlConnection(Environment.GetEnvironmentVariable("CONNSTR")))
101 | using (var command = new SqlCommand("select count(*) from SchemaVersions where scriptname = '001.sql'", connection))
102 | {
103 | Action a = () => connection.Open();
104 | a.Should().Throw("Database DbUp should not exist");
105 | }
106 | }
107 |
108 | [TestMethod]
109 | public void UpgradeCommand_ShouldUseConnectionTimeoutForLongrunningQueries()
110 | {
111 | var engine = new ToolEngine(Env, Logger);
112 |
113 | var r = engine.Run("upgrade", "--ensure", GetConfigPath("dbup.yml", "Timeout"));
114 | r.Should().Be(1);
115 | }
116 |
117 | [TestMethod]
118 | public void UpgradeCommand_ShouldUseASpecifiedJournal()
119 | {
120 | var engine = new ToolEngine(Env, Logger);
121 |
122 | var result = engine.Run("upgrade", "--ensure", GetConfigPath("dbup.yml", "JournalTableScript"));
123 | result.Should().Be(0);
124 |
125 | using (var connection = new SqlConnection(Environment.GetEnvironmentVariable("CONNSTR")))
126 | using (var command = new SqlCommand("select count(*) from dbo.testTable where scriptname = '001.sql'", connection))
127 | {
128 | connection.Open();
129 | var count = command.ExecuteScalar();
130 |
131 | count.Should().Be(1);
132 | }
133 | }
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/src/dbup-cli.integration-tests/dbup-cli.integration-tests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp2.1;netcoreapp3.1;net5.0;net6.0;net7.0
5 | DbUp.Cli.IntegrationTests
6 |
7 | false
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | PreserveNewest
29 |
30 |
31 | PreserveNewest
32 |
33 |
34 | PreserveNewest
35 |
36 |
37 | PreserveNewest
38 |
39 |
40 | PreserveNewest
41 |
42 |
43 | PreserveNewest
44 |
45 |
46 | PreserveNewest
47 |
48 |
49 | PreserveNewest
50 |
51 |
52 | PreserveNewest
53 |
54 |
55 | PreserveNewest
56 |
57 |
58 | PreserveNewest
59 |
60 |
61 | PreserveNewest
62 |
63 |
64 | PreserveNewest
65 |
66 |
67 | PreserveNewest
68 |
69 |
70 | PreserveNewest
71 |
72 |
73 | PreserveNewest
74 |
75 |
76 | PreserveNewest
77 |
78 |
79 | PreserveNewest
80 |
81 |
82 | PreserveNewest
83 |
84 |
85 | PreserveNewest
86 |
87 |
88 | PreserveNewest
89 |
90 |
91 | PreserveNewest
92 |
93 |
94 | PreserveNewest
95 |
96 |
97 | PreserveNewest
98 |
99 |
100 | PreserveNewest
101 |
102 |
103 | PreserveNewest
104 |
105 |
106 |
107 |
108 |
--------------------------------------------------------------------------------
/src/dbup-cli.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.28307.329
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dbup-cli", "dbup-cli\dbup-cli.csproj", "{97DCD633-B24A-459E-B781-56D4E49F9879}"
7 | EndProject
8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dbup-cli.integration-tests", "dbup-cli.integration-tests\dbup-cli.integration-tests.csproj", "{7E7DA3A5-AD27-4789-882A-D6C58924721B}"
9 | EndProject
10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dbup-cli.tests.core", "dbup-cli.tests.core\dbup-cli.tests.core.csproj", "{8B42CF74-0B01-4A59-85F3-90515D079B6E}"
11 | EndProject
12 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dbup-cli.tests", "dbup-cli.tests\dbup-cli.tests.csproj", "{66AAAC19-6161-4898-A201-C0F3D9C88849}"
13 | EndProject
14 | Global
15 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
16 | Debug|Any CPU = Debug|Any CPU
17 | Release|Any CPU = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
20 | {97DCD633-B24A-459E-B781-56D4E49F9879}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21 | {97DCD633-B24A-459E-B781-56D4E49F9879}.Debug|Any CPU.Build.0 = Debug|Any CPU
22 | {97DCD633-B24A-459E-B781-56D4E49F9879}.Release|Any CPU.ActiveCfg = Release|Any CPU
23 | {97DCD633-B24A-459E-B781-56D4E49F9879}.Release|Any CPU.Build.0 = Release|Any CPU
24 | {7E7DA3A5-AD27-4789-882A-D6C58924721B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
25 | {7E7DA3A5-AD27-4789-882A-D6C58924721B}.Debug|Any CPU.Build.0 = Debug|Any CPU
26 | {7E7DA3A5-AD27-4789-882A-D6C58924721B}.Release|Any CPU.ActiveCfg = Release|Any CPU
27 | {7E7DA3A5-AD27-4789-882A-D6C58924721B}.Release|Any CPU.Build.0 = Release|Any CPU
28 | {8B42CF74-0B01-4A59-85F3-90515D079B6E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
29 | {8B42CF74-0B01-4A59-85F3-90515D079B6E}.Debug|Any CPU.Build.0 = Debug|Any CPU
30 | {8B42CF74-0B01-4A59-85F3-90515D079B6E}.Release|Any CPU.ActiveCfg = Release|Any CPU
31 | {8B42CF74-0B01-4A59-85F3-90515D079B6E}.Release|Any CPU.Build.0 = Release|Any CPU
32 | {66AAAC19-6161-4898-A201-C0F3D9C88849}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
33 | {66AAAC19-6161-4898-A201-C0F3D9C88849}.Debug|Any CPU.Build.0 = Debug|Any CPU
34 | {66AAAC19-6161-4898-A201-C0F3D9C88849}.Release|Any CPU.ActiveCfg = Release|Any CPU
35 | {66AAAC19-6161-4898-A201-C0F3D9C88849}.Release|Any CPU.Build.0 = Release|Any CPU
36 | EndGlobalSection
37 | GlobalSection(SolutionProperties) = preSolution
38 | HideSolutionNode = FALSE
39 | EndGlobalSection
40 | GlobalSection(ExtensibilityGlobals) = postSolution
41 | SolutionGuid = {ECE47877-4066-4EBC-BB5F-2AAAE5EDFFBB}
42 | EndGlobalSection
43 | EndGlobal
44 |
--------------------------------------------------------------------------------
/src/dbup-cli.tests.core/TestInfrastructure/CaptureLogsLogger.cs:
--------------------------------------------------------------------------------
1 | using DbUp.Engine.Output;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Text;
5 |
6 | namespace DbUp.Cli.Tests.TestInfrastructure
7 | {
8 | public class CaptureLogsLogger: IUpgradeLog
9 | {
10 | readonly StringBuilder logBuilder = new StringBuilder();
11 | public List InfoMessages { get; } = new List();
12 | public List WarnMessages { get; } = new List();
13 | public List ErrorMessages { get; } = new List();
14 |
15 | public string Log => logBuilder.ToString();
16 |
17 | public void WriteInformation(string format, params object[] args)
18 | {
19 | var formattedMsg = string.Format(format, args);
20 | var value = "Info: " + formattedMsg;
21 | Console.WriteLine(value);
22 | logBuilder.AppendLine(value);
23 | InfoMessages.Add(formattedMsg);
24 | }
25 |
26 | public void WriteWarning(string format, params object[] args)
27 | {
28 | var formattedValue = string.Format(format, args);
29 | var value = "Warn: " + formattedValue;
30 | Console.WriteLine(value);
31 | logBuilder.AppendLine(value);
32 | WarnMessages.Add(formattedValue);
33 | }
34 |
35 | public void WriteError(string format, params object[] args)
36 | {
37 | var formattedMessage = string.Format(format, args);
38 | var value = "Error: " + formattedMessage;
39 | Console.WriteLine(value);
40 | logBuilder.AppendLine(value);
41 | ErrorMessages.Add(formattedMessage);
42 | }
43 |
44 | public void WriteDbOperation(string operation)
45 | {
46 | var value = "DB Operation: " + operation;
47 | Console.WriteLine(value);
48 | logBuilder.AppendLine(value);
49 | }
50 | }
51 | }
--------------------------------------------------------------------------------
/src/dbup-cli.tests.core/TestInfrastructure/CaptureLogsLoggerExtensions.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Text.RegularExpressions;
3 |
4 | namespace DbUp.Cli.Tests.TestInfrastructure
5 | {
6 | static public class CaptureLogsLoggerExtensions
7 | {
8 | public static List GetExecutedScripts(this CaptureLogsLogger logger)
9 | {
10 | var scripts = new List();
11 | var exp = new Regex(@"Executing Database Server script '(.+\.sql)'");
12 | foreach (var msg in logger.InfoMessages)
13 | {
14 | var m = exp.Match(msg);
15 | if (!m.Success)
16 | {
17 | continue;
18 | }
19 |
20 | scripts.Add(m.Groups[1].Value);
21 | }
22 |
23 | return scripts;
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/dbup-cli.tests.core/TestInfrastructure/EmptyReader.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Data;
3 |
4 | namespace DbUp.Cli.Tests.TestInfrastructure
5 | {
6 | public class EmptyReader: IDataReader
7 | {
8 | public bool GetBoolean(int i)
9 | {
10 | throw new NotImplementedException();
11 | }
12 |
13 | public byte GetByte(int i)
14 | {
15 | throw new NotImplementedException();
16 | }
17 |
18 | public long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length)
19 | {
20 | throw new NotImplementedException();
21 | }
22 |
23 | public char GetChar(int i)
24 | {
25 | throw new NotImplementedException();
26 | }
27 |
28 | public long GetChars(int i, long fieldoffset, char[] buffer, int bufferoffset, int length)
29 | {
30 | throw new NotImplementedException();
31 | }
32 |
33 | public IDataReader GetData(int i)
34 | {
35 | throw new NotImplementedException();
36 | }
37 |
38 | public string GetDataTypeName(int i)
39 | {
40 | throw new NotImplementedException();
41 | }
42 |
43 | public DateTime GetDateTime(int i)
44 | {
45 | throw new NotImplementedException();
46 | }
47 |
48 | public decimal GetDecimal(int i)
49 | {
50 | throw new NotImplementedException();
51 | }
52 |
53 | public double GetDouble(int i)
54 | {
55 | throw new NotImplementedException();
56 | }
57 |
58 | public Type GetFieldType(int i)
59 | {
60 | throw new NotImplementedException();
61 | }
62 |
63 | public float GetFloat(int i)
64 | {
65 | throw new NotImplementedException();
66 | }
67 |
68 | public Guid GetGuid(int i)
69 | {
70 | throw new NotImplementedException();
71 | }
72 |
73 | public short GetInt16(int i)
74 | {
75 | throw new NotImplementedException();
76 | }
77 |
78 | public int GetInt32(int i)
79 | {
80 | throw new NotImplementedException();
81 | }
82 |
83 | public long GetInt64(int i)
84 | {
85 | throw new NotImplementedException();
86 | }
87 |
88 | public string GetName(int i)
89 | {
90 | throw new NotImplementedException();
91 | }
92 |
93 | public int GetOrdinal(string name)
94 | {
95 | throw new NotImplementedException();
96 | }
97 |
98 | public string GetString(int i)
99 | {
100 | throw new NotImplementedException();
101 | }
102 |
103 | public object GetValue(int i)
104 | {
105 | throw new NotImplementedException();
106 | }
107 |
108 | public int GetValues(object[] values)
109 | {
110 | throw new NotImplementedException();
111 | }
112 |
113 | public bool IsDBNull(int i)
114 | {
115 | throw new NotImplementedException();
116 | }
117 |
118 | public int FieldCount { get; }
119 |
120 | object IDataRecord.this[string name]
121 | {
122 | get { throw new NotImplementedException(); }
123 | }
124 |
125 | object IDataRecord.this[int i]
126 | {
127 | get { throw new NotImplementedException(); }
128 | }
129 |
130 | public void Dispose()
131 | {
132 | }
133 |
134 | public void Close()
135 | {
136 | }
137 |
138 | public DataTable GetSchemaTable()
139 | {
140 | throw new NotImplementedException();
141 | }
142 |
143 | public bool NextResult()
144 | {
145 | throw new NotImplementedException();
146 | }
147 |
148 | public bool Read()
149 | {
150 | return false;
151 | }
152 |
153 | public int Depth { get; }
154 | public bool IsClosed { get; }
155 | public int RecordsAffected { get; }
156 | }
157 | }
--------------------------------------------------------------------------------
/src/dbup-cli.tests.core/TestInfrastructure/RecordingDataParameterCollection.cs:
--------------------------------------------------------------------------------
1 | using DbUp.Engine.Output;
2 | using System;
3 | using System.Collections;
4 | using System.Collections.Generic;
5 | using System.Data;
6 |
7 | namespace DbUp.Cli.Tests.TestInfrastructure
8 | {
9 | public class RecordingDataParameterCollection: IDataParameterCollection
10 | {
11 | readonly IUpgradeLog logger;
12 | readonly List