You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1167 lines
43 KiB

10 years ago
  1. # Copyright (c) Microsoft Corporation. All rights reserved.
  2. $InitialDatabase = '0'
  3. $knownExceptions = @(
  4. 'System.Data.Entity.Migrations.Infrastructure.MigrationsException',
  5. 'System.Data.Entity.Migrations.Infrastructure.AutomaticMigrationsDisabledException',
  6. 'System.Data.Entity.Migrations.Infrastructure.AutomaticDataLossException',
  7. 'System.Data.Entity.Migrations.Infrastructure.MigrationsPendingException',
  8. 'System.Data.Entity.Migrations.ProjectTypeNotSupportedException'
  9. )
  10. <#
  11. .SYNOPSIS
  12. Adds or updates an Entity Framework provider entry in the project config
  13. file.
  14. .DESCRIPTION
  15. Adds an entry into the 'entityFramework' section of the project config
  16. file for the specified provider invariant name and provider type. If an
  17. entry for the given invariant name already exists, then that entry is
  18. updated with the given type name, unless the given type name already
  19. matches, in which case no action is taken. The 'entityFramework'
  20. section is added if it does not exist. The config file is automatically
  21. saved if and only if a change was made.
  22. This command is typically used only by Entity Framework provider NuGet
  23. packages and is run from the 'install.ps1' script.
  24. .PARAMETER Project
  25. The Visual Studio project to update. When running in the NuGet install.ps1
  26. script the '$project' variable provided as part of that script should be
  27. used.
  28. .PARAMETER InvariantName
  29. The provider invariant name that uniquely identifies this provider. For
  30. example, the Microsoft SQL Server provider is registered with the invariant
  31. name 'System.Data.SqlClient'.
  32. .PARAMETER TypeName
  33. The assembly-qualified type name of the provider-specific type that
  34. inherits from 'System.Data.Entity.Core.Common.DbProviderServices'. For
  35. example, for the Microsoft SQL Server provider, this type is
  36. 'System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer'.
  37. #>
  38. function Add-EFProvider
  39. {
  40. param (
  41. [parameter(Position = 0,
  42. Mandatory = $true)]
  43. $Project,
  44. [parameter(Position = 1,
  45. Mandatory = $true)]
  46. [string] $InvariantName,
  47. [parameter(Position = 2,
  48. Mandatory = $true)]
  49. [string] $TypeName
  50. )
  51. if (!(Check-Project $project))
  52. {
  53. return
  54. }
  55. $runner = New-EFConfigRunner $Project
  56. try
  57. {
  58. Invoke-RunnerCommand $runner System.Data.Entity.ConnectionFactoryConfig.AddProviderCommand @( $InvariantName, $TypeName )
  59. $error = Get-RunnerError $runner
  60. if ($error)
  61. {
  62. if ($knownExceptions -notcontains $error.TypeName)
  63. {
  64. Write-Host $error.StackTrace
  65. }
  66. else
  67. {
  68. Write-Verbose $error.StackTrace
  69. }
  70. throw $error.Message
  71. }
  72. }
  73. finally
  74. {
  75. Remove-Runner $runner
  76. }
  77. }
  78. <#
  79. .SYNOPSIS
  80. Adds or updates an Entity Framework default connection factory in the
  81. project config file.
  82. .DESCRIPTION
  83. Adds an entry into the 'entityFramework' section of the project config
  84. file for the connection factory that Entity Framework will use by default
  85. when creating new connections by convention. Any existing entry will be
  86. overridden if it does not match. The 'entityFramework' section is added if
  87. it does not exist. The config file is automatically saved if and only if
  88. a change was made.
  89. This command is typically used only by Entity Framework provider NuGet
  90. packages and is run from the 'install.ps1' script.
  91. .PARAMETER Project
  92. The Visual Studio project to update. When running in the NuGet install.ps1
  93. script the '$project' variable provided as part of that script should be
  94. used.
  95. .PARAMETER TypeName
  96. The assembly-qualified type name of the connection factory type that
  97. implements the 'System.Data.Entity.Infrastructure.IDbConnectionFactory'
  98. interface. For example, for the Microsoft SQL Server Express provider
  99. connection factory, this type is
  100. 'System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework'.
  101. .PARAMETER ConstructorArguments
  102. An optional array of strings that will be passed as arguments to the
  103. connection factory type constructor.
  104. #>
  105. function Add-EFDefaultConnectionFactory
  106. {
  107. param (
  108. [parameter(Position = 0,
  109. Mandatory = $true)]
  110. $Project,
  111. [parameter(Position = 1,
  112. Mandatory = $true)]
  113. [string] $TypeName,
  114. [string[]] $ConstructorArguments
  115. )
  116. if (!(Check-Project $project))
  117. {
  118. return
  119. }
  120. $runner = New-EFConfigRunner $Project
  121. try
  122. {
  123. Invoke-RunnerCommand $runner System.Data.Entity.ConnectionFactoryConfig.AddDefaultConnectionFactoryCommand @( $TypeName, $ConstructorArguments )
  124. $error = Get-RunnerError $runner
  125. if ($error)
  126. {
  127. if ($knownExceptions -notcontains $error.TypeName)
  128. {
  129. Write-Host $error.StackTrace
  130. }
  131. else
  132. {
  133. Write-Verbose $error.StackTrace
  134. }
  135. throw $error.Message
  136. }
  137. }
  138. finally
  139. {
  140. Remove-Runner $runner
  141. }
  142. }
  143. <#
  144. .SYNOPSIS
  145. Initializes the Entity Framework section in the project config file
  146. and sets defaults.
  147. .DESCRIPTION
  148. Creates the 'entityFramework' section of the project config file and sets
  149. the default connection factory to use SQL Express if it is running on the
  150. machine, or LocalDb otherwise. Note that installing a different provider
  151. may change the default connection factory. The config file is
  152. automatically saved if and only if a change was made.
  153. In addition, any reference to 'System.Data.Entity.dll' in the project is
  154. removed.
  155. This command is typically used only by Entity Framework provider NuGet
  156. packages and is run from the 'install.ps1' script.
  157. .PARAMETER Project
  158. The Visual Studio project to update. When running in the NuGet install.ps1
  159. script the '$project' variable provided as part of that script should be
  160. used.
  161. #>
  162. function Initialize-EFConfiguration
  163. {
  164. param (
  165. [parameter(Position = 0,
  166. Mandatory = $true)]
  167. $Project
  168. )
  169. if (!(Check-Project $project))
  170. {
  171. return
  172. }
  173. $runner = New-EFConfigRunner $Project
  174. try
  175. {
  176. Invoke-RunnerCommand $runner System.Data.Entity.ConnectionFactoryConfig.InitializeEntityFrameworkCommand
  177. $error = Get-RunnerError $runner
  178. if ($error)
  179. {
  180. if ($knownExceptions -notcontains $error.TypeName)
  181. {
  182. Write-Host $error.StackTrace
  183. }
  184. else
  185. {
  186. Write-Verbose $error.StackTrace
  187. }
  188. throw $error.Message
  189. }
  190. }
  191. finally
  192. {
  193. Remove-Runner $runner
  194. }
  195. }
  196. <#
  197. .SYNOPSIS
  198. Enables Code First Migrations in a project.
  199. .DESCRIPTION
  200. Enables Migrations by scaffolding a migrations configuration class in the project. If the
  201. target database was created by an initializer, an initial migration will be created (unless
  202. automatic migrations are enabled via the EnableAutomaticMigrations parameter).
  203. .PARAMETER ContextTypeName
  204. Specifies the context to use. If omitted, migrations will attempt to locate a
  205. single context type in the target project.
  206. .PARAMETER EnableAutomaticMigrations
  207. Specifies whether automatic migrations will be enabled in the scaffolded migrations configuration.
  208. If omitted, automatic migrations will be disabled.
  209. .PARAMETER MigrationsDirectory
  210. Specifies the name of the directory that will contain migrations code files.
  211. If omitted, the directory will be named "Migrations".
  212. .PARAMETER ProjectName
  213. Specifies the project that the scaffolded migrations configuration class will
  214. be added to. If omitted, the default project selected in package manager
  215. console is used.
  216. .PARAMETER StartUpProjectName
  217. Specifies the configuration file to use for named connection strings. If
  218. omitted, the specified project's configuration file is used.
  219. .PARAMETER ContextProjectName
  220. Specifies the project which contains the DbContext class to use. If omitted,
  221. the context is assumed to be in the same project used for migrations.
  222. .PARAMETER ConnectionStringName
  223. Specifies the name of a connection string to use from the application's
  224. configuration file.
  225. .PARAMETER ConnectionString
  226. Specifies the the connection string to use. If omitted, the context's
  227. default connection will be used.
  228. .PARAMETER ConnectionProviderName
  229. Specifies the provider invariant name of the connection string.
  230. .PARAMETER Force
  231. Specifies that the migrations configuration be overwritten when running more
  232. than once for a given project.
  233. .PARAMETER ContextAssemblyName
  234. Specifies the name of the assembly which contains the DbContext class to use. Use this
  235. parameter instead of ContextProjectName when the context is contained in a referenced
  236. assembly rather than in a project of the solution.
  237. .PARAMETER AppDomainBaseDirectory
  238. Specifies the directory to use for the app-domain that is used for running Migrations
  239. code such that the app-domain is able to find all required assemblies. This is an
  240. advanced option that should only be needed if the solution contains several projects
  241. such that the assemblies needed for the context and configuration are not all
  242. referenced from either the project containing the context or the project containing
  243. the migrations.
  244. .EXAMPLE
  245. Enable-Migrations
  246. # Scaffold a migrations configuration in a project with only one context
  247. .EXAMPLE
  248. Enable-Migrations -Auto
  249. # Scaffold a migrations configuration with automatic migrations enabled for a project
  250. # with only one context
  251. .EXAMPLE
  252. Enable-Migrations -ContextTypeName MyContext -MigrationsDirectory DirectoryName
  253. # Scaffold a migrations configuration for a project with multiple contexts
  254. # This scaffolds a migrations configuration for MyContext and will put the configuration
  255. # and subsequent configurations in a new directory called "DirectoryName"
  256. #>
  257. function Enable-Migrations
  258. {
  259. [CmdletBinding(DefaultParameterSetName = 'ConnectionStringName')]
  260. param (
  261. [string] $ContextTypeName,
  262. [alias('Auto')]
  263. [switch] $EnableAutomaticMigrations,
  264. [string] $MigrationsDirectory,
  265. [string] $ProjectName,
  266. [string] $StartUpProjectName,
  267. [string] $ContextProjectName,
  268. [parameter(ParameterSetName = 'ConnectionStringName')]
  269. [string] $ConnectionStringName,
  270. [parameter(ParameterSetName = 'ConnectionStringAndProviderName',
  271. Mandatory = $true)]
  272. [string] $ConnectionString,
  273. [parameter(ParameterSetName = 'ConnectionStringAndProviderName',
  274. Mandatory = $true)]
  275. [string] $ConnectionProviderName,
  276. [switch] $Force,
  277. [string] $ContextAssemblyName,
  278. [string] $AppDomainBaseDirectory
  279. )
  280. $runner = New-MigrationsRunner $ProjectName $StartUpProjectName $ContextProjectName $null $ConnectionStringName $ConnectionString $ConnectionProviderName $ContextAssemblyName $AppDomainBaseDirectory
  281. try
  282. {
  283. Invoke-RunnerCommand $runner System.Data.Entity.Migrations.EnableMigrationsCommand @( $EnableAutomaticMigrations.IsPresent, $Force.IsPresent ) @{ 'ContextTypeName' = $ContextTypeName; 'MigrationsDirectory' = $MigrationsDirectory }
  284. $error = Get-RunnerError $runner
  285. if ($error)
  286. {
  287. if ($knownExceptions -notcontains $error.TypeName)
  288. {
  289. Write-Host $error.StackTrace
  290. }
  291. else
  292. {
  293. Write-Verbose $error.StackTrace
  294. }
  295. throw $error.Message
  296. }
  297. $(Get-VSComponentModel).GetService([NuGetConsole.IPowerConsoleWindow]).Show()
  298. }
  299. finally
  300. {
  301. Remove-Runner $runner
  302. }
  303. }
  304. <#
  305. .SYNOPSIS
  306. Scaffolds a migration script for any pending model changes.
  307. .DESCRIPTION
  308. Scaffolds a new migration script and adds it to the project.
  309. .PARAMETER Name
  310. Specifies the name of the custom script.
  311. .PARAMETER Force
  312. Specifies that the migration user code be overwritten when re-scaffolding an
  313. existing migration.
  314. .PARAMETER ProjectName
  315. Specifies the project that contains the migration configuration type to be
  316. used. If omitted, the default project selected in package manager console
  317. is used.
  318. .PARAMETER StartUpProjectName
  319. Specifies the configuration file to use for named connection strings. If
  320. omitted, the specified project's configuration file is used.
  321. .PARAMETER ConfigurationTypeName
  322. Specifies the migrations configuration to use. If omitted, migrations will
  323. attempt to locate a single migrations configuration type in the target
  324. project.
  325. .PARAMETER ConnectionStringName
  326. Specifies the name of a connection string to use from the application's
  327. configuration file.
  328. .PARAMETER ConnectionString
  329. Specifies the the connection string to use. If omitted, the context's
  330. default connection will be used.
  331. .PARAMETER ConnectionProviderName
  332. Specifies the provider invariant name of the connection string.
  333. .PARAMETER IgnoreChanges
  334. Scaffolds an empty migration ignoring any pending changes detected in the current model.
  335. This can be used to create an initial, empty migration to enable Migrations for an existing
  336. database. N.B. Doing this assumes that the target database schema is compatible with the
  337. current model.
  338. .PARAMETER AppDomainBaseDirectory
  339. Specifies the directory to use for the app-domain that is used for running Migrations
  340. code such that the app-domain is able to find all required assemblies. This is an
  341. advanced option that should only be needed if the solution contains several projects
  342. such that the assemblies needed for the context and configuration are not all
  343. referenced from either the project containing the context or the project containing
  344. the migrations.
  345. .EXAMPLE
  346. Add-Migration First
  347. # Scaffold a new migration named "First"
  348. .EXAMPLE
  349. Add-Migration First -IgnoreChanges
  350. # Scaffold an empty migration ignoring any pending changes detected in the current model.
  351. # This can be used to create an initial, empty migration to enable Migrations for an existing
  352. # database. N.B. Doing this assumes that the target database schema is compatible with the
  353. # current model.
  354. #>
  355. function Add-Migration
  356. {
  357. [CmdletBinding(DefaultParameterSetName = 'ConnectionStringName')]
  358. param (
  359. [parameter(Position = 0,
  360. Mandatory = $true)]
  361. [string] $Name,
  362. [switch] $Force,
  363. [string] $ProjectName,
  364. [string] $StartUpProjectName,
  365. [string] $ConfigurationTypeName,
  366. [parameter(ParameterSetName = 'ConnectionStringName')]
  367. [string] $ConnectionStringName,
  368. [parameter(ParameterSetName = 'ConnectionStringAndProviderName',
  369. Mandatory = $true)]
  370. [string] $ConnectionString,
  371. [parameter(ParameterSetName = 'ConnectionStringAndProviderName',
  372. Mandatory = $true)]
  373. [string] $ConnectionProviderName,
  374. [switch] $IgnoreChanges,
  375. [string] $AppDomainBaseDirectory)
  376. $runner = New-MigrationsRunner $ProjectName $StartUpProjectName $null $ConfigurationTypeName $ConnectionStringName $ConnectionString $ConnectionProviderName $null $AppDomainBaseDirectory
  377. try
  378. {
  379. Invoke-RunnerCommand $runner System.Data.Entity.Migrations.AddMigrationCommand @( $Name, $Force.IsPresent, $IgnoreChanges.IsPresent )
  380. $error = Get-RunnerError $runner
  381. if ($error)
  382. {
  383. if ($knownExceptions -notcontains $error.TypeName)
  384. {
  385. Write-Host $error.StackTrace
  386. }
  387. else
  388. {
  389. Write-Verbose $error.StackTrace
  390. }
  391. throw $error.Message
  392. }
  393. $(Get-VSComponentModel).GetService([NuGetConsole.IPowerConsoleWindow]).Show()
  394. }
  395. finally
  396. {
  397. Remove-Runner $runner
  398. }
  399. }
  400. <#
  401. .SYNOPSIS
  402. Applies any pending migrations to the database.
  403. .DESCRIPTION
  404. Updates the database to the current model by applying pending migrations.
  405. .PARAMETER SourceMigration
  406. Only valid with -Script. Specifies the name of a particular migration to use
  407. as the update's starting point. If omitted, the last applied migration in
  408. the database will be used.
  409. .PARAMETER TargetMigration
  410. Specifies the name of a particular migration to update the database to. If
  411. omitted, the current model will be used.
  412. .PARAMETER Script
  413. Generate a SQL script rather than executing the pending changes directly.
  414. .PARAMETER Force
  415. Specifies that data loss is acceptable during automatic migration of the
  416. database.
  417. .PARAMETER ProjectName
  418. Specifies the project that contains the migration configuration type to be
  419. used. If omitted, the default project selected in package manager console
  420. is used.
  421. .PARAMETER StartUpProjectName
  422. Specifies the configuration file to use for named connection strings. If
  423. omitted, the specified project's configuration file is used.
  424. .PARAMETER ConfigurationTypeName
  425. Specifies the migrations configuration to use. If omitted, migrations will
  426. attempt to locate a single migrations configuration type in the target
  427. project.
  428. .PARAMETER ConnectionStringName
  429. Specifies the name of a connection string to use from the application's
  430. configuration file.
  431. .PARAMETER ConnectionString
  432. Specifies the the connection string to use. If omitted, the context's
  433. default connection will be used.
  434. .PARAMETER ConnectionProviderName
  435. Specifies the provider invariant name of the connection string.
  436. .PARAMETER AppDomainBaseDirectory
  437. Specifies the directory to use for the app-domain that is used for running Migrations
  438. code such that the app-domain is able to find all required assemblies. This is an
  439. advanced option that should only be needed if the solution contains several projects
  440. such that the assemblies needed for the context and configuration are not all
  441. referenced from either the project containing the context or the project containing
  442. the migrations.
  443. .EXAMPLE
  444. Update-Database
  445. # Update the database to the latest migration
  446. .EXAMPLE
  447. Update-Database -TargetMigration Second
  448. # Update database to a migration named "Second"
  449. # This will apply migrations if the target hasn't been applied or roll back migrations
  450. # if it has
  451. .EXAMPLE
  452. Update-Database -Script
  453. # Generate a script to update the database from it's current state to the latest migration
  454. .EXAMPLE
  455. Update-Database -Script -SourceMigration Second -TargetMigration First
  456. # Generate a script to migrate the database from a specified start migration
  457. # named "Second" to a specified target migration named "First"
  458. .EXAMPLE
  459. Update-Database -Script -SourceMigration $InitialDatabase
  460. # Generate a script that can upgrade a database currently at any version to the latest version.
  461. # The generated script includes logic to check the __MigrationsHistory table and only apply changes
  462. # that haven't been previously applied.
  463. .EXAMPLE
  464. Update-Database -TargetMigration $InitialDatabase
  465. # Runs the Down method to roll-back any migrations that have been applied to the database
  466. #>
  467. function Update-Database
  468. {
  469. [CmdletBinding(DefaultParameterSetName = 'ConnectionStringName')]
  470. param (
  471. [string] $SourceMigration,
  472. [string] $TargetMigration,
  473. [switch] $Script,
  474. [switch] $Force,
  475. [string] $ProjectName,
  476. [string] $StartUpProjectName,
  477. [string] $ConfigurationTypeName,
  478. [parameter(ParameterSetName = 'ConnectionStringName')]
  479. [string] $ConnectionStringName,
  480. [parameter(ParameterSetName = 'ConnectionStringAndProviderName',
  481. Mandatory = $true)]
  482. [string] $ConnectionString,
  483. [parameter(ParameterSetName = 'ConnectionStringAndProviderName',
  484. Mandatory = $true)]
  485. [string] $ConnectionProviderName,
  486. [string] $AppDomainBaseDirectory)
  487. $runner = New-MigrationsRunner $ProjectName $StartUpProjectName $null $ConfigurationTypeName $ConnectionStringName $ConnectionString $ConnectionProviderName $null $AppDomainBaseDirectory
  488. try
  489. {
  490. Invoke-RunnerCommand $runner System.Data.Entity.Migrations.UpdateDatabaseCommand @( $SourceMigration, $TargetMigration, $Script.IsPresent, $Force.IsPresent, $Verbose.IsPresent )
  491. $error = Get-RunnerError $runner
  492. if ($error)
  493. {
  494. if ($knownExceptions -notcontains $error.TypeName)
  495. {
  496. Write-Host $error.StackTrace
  497. }
  498. else
  499. {
  500. Write-Verbose $error.StackTrace
  501. }
  502. throw $error.Message
  503. }
  504. $(Get-VSComponentModel).GetService([NuGetConsole.IPowerConsoleWindow]).Show()
  505. }
  506. finally
  507. {
  508. Remove-Runner $runner
  509. }
  510. }
  511. <#
  512. .SYNOPSIS
  513. Displays the migrations that have been applied to the target database.
  514. .DESCRIPTION
  515. Displays the migrations that have been applied to the target database.
  516. .PARAMETER ProjectName
  517. Specifies the project that contains the migration configuration type to be
  518. used. If omitted, the default project selected in package manager console
  519. is used.
  520. .PARAMETER StartUpProjectName
  521. Specifies the configuration file to use for named connection strings. If
  522. omitted, the specified project's configuration file is used.
  523. .PARAMETER ConfigurationTypeName
  524. Specifies the migrations configuration to use. If omitted, migrations will
  525. attempt to locate a single migrations configuration type in the target
  526. project.
  527. .PARAMETER ConnectionStringName
  528. Specifies the name of a connection string to use from the application's
  529. configuration file.
  530. .PARAMETER ConnectionString
  531. Specifies the the connection string to use. If omitted, the context's
  532. default connection will be used.
  533. .PARAMETER ConnectionProviderName
  534. Specifies the provider invariant name of the connection string.
  535. .PARAMETER AppDomainBaseDirectory
  536. Specifies the directory to use for the app-domain that is used for running Migrations
  537. code such that the app-domain is able to find all required assemblies. This is an
  538. advanced option that should only be needed if the solution contains several projects
  539. such that the assemblies needed for the context and configuration are not all
  540. referenced from either the project containing the context or the project containing
  541. the migrations.
  542. #>
  543. function Get-Migrations
  544. {
  545. [CmdletBinding(DefaultParameterSetName = 'ConnectionStringName')]
  546. param (
  547. [string] $ProjectName,
  548. [string] $StartUpProjectName,
  549. [string] $ConfigurationTypeName,
  550. [parameter(ParameterSetName = 'ConnectionStringName')]
  551. [string] $ConnectionStringName,
  552. [parameter(ParameterSetName = 'ConnectionStringAndProviderName',
  553. Mandatory = $true)]
  554. [string] $ConnectionString,
  555. [parameter(ParameterSetName = 'ConnectionStringAndProviderName',
  556. Mandatory = $true)]
  557. [string] $ConnectionProviderName,
  558. [string] $AppDomainBaseDirectory)
  559. $runner = New-MigrationsRunner $ProjectName $StartUpProjectName $null $ConfigurationTypeName $ConnectionStringName $ConnectionString $ConnectionProviderName $null $AppDomainBaseDirectory
  560. try
  561. {
  562. Invoke-RunnerCommand $runner System.Data.Entity.Migrations.GetMigrationsCommand
  563. $error = Get-RunnerError $runner
  564. if ($error)
  565. {
  566. if ($knownExceptions -notcontains $error.TypeName)
  567. {
  568. Write-Host $error.StackTrace
  569. }
  570. else
  571. {
  572. Write-Verbose $error.StackTrace
  573. }
  574. throw $error.Message
  575. }
  576. }
  577. finally
  578. {
  579. Remove-Runner $runner
  580. }
  581. }
  582. function New-MigrationsRunner($ProjectName, $StartUpProjectName, $ContextProjectName, $ConfigurationTypeName, $ConnectionStringName, $ConnectionString, $ConnectionProviderName, $ContextAssemblyName, $AppDomainBaseDirectory)
  583. {
  584. $startUpProject = Get-MigrationsStartUpProject $StartUpProjectName $ProjectName
  585. Build-Project $startUpProject
  586. $project = Get-MigrationsProject $ProjectName
  587. Build-Project $project
  588. $contextProject = $project
  589. if ($ContextProjectName)
  590. {
  591. $contextProject = Get-SingleProject $ContextProjectName
  592. Build-Project $contextProject
  593. }
  594. $installPath = Get-EntityFrameworkInstallPath $project
  595. $toolsPath = Join-Path $installPath tools
  596. $info = New-AppDomainSetup $project $installPath
  597. $domain = [AppDomain]::CreateDomain('Migrations', $null, $info)
  598. $domain.SetData('project', $project)
  599. $domain.SetData('contextProject', $contextProject)
  600. $domain.SetData('startUpProject', $startUpProject)
  601. $domain.SetData('configurationTypeName', $ConfigurationTypeName)
  602. $domain.SetData('connectionStringName', $ConnectionStringName)
  603. $domain.SetData('connectionString', $ConnectionString)
  604. $domain.SetData('connectionProviderName', $ConnectionProviderName)
  605. $domain.SetData('contextAssemblyName', $ContextAssemblyName)
  606. $domain.SetData('appDomainBaseDirectory', $AppDomainBaseDirectory)
  607. $dispatcher = New-DomainDispatcher $toolsPath
  608. $domain.SetData('efDispatcher', $dispatcher)
  609. return @{
  610. Domain = $domain;
  611. ToolsPath = $toolsPath
  612. }
  613. }
  614. function New-EFConfigRunner($Project)
  615. {
  616. $installPath = Get-EntityFrameworkInstallPath $Project
  617. $toolsPath = Join-Path $installPath tools
  618. $info = New-AppDomainSetup $Project $installPath
  619. $domain = [AppDomain]::CreateDomain('EFConfig', $null, $info)
  620. $domain.SetData('project', $Project)
  621. $dispatcher = New-DomainDispatcher $toolsPath
  622. $domain.SetData('efDispatcher', $dispatcher)
  623. return @{
  624. Domain = $domain;
  625. ToolsPath = $toolsPath
  626. }
  627. }
  628. function New-AppDomainSetup($Project, $InstallPath)
  629. {
  630. $info = New-Object System.AppDomainSetup -Property @{
  631. ShadowCopyFiles = 'true';
  632. ApplicationBase = $InstallPath;
  633. PrivateBinPath = 'tools';
  634. ConfigurationFile = ([AppDomain]::CurrentDomain.SetupInformation.ConfigurationFile)
  635. }
  636. $targetFrameworkVersion = (New-Object System.Runtime.Versioning.FrameworkName ($Project.Properties.Item('TargetFrameworkMoniker').Value)).Version
  637. if ($targetFrameworkVersion -lt (New-Object Version @( 4, 5 )))
  638. {
  639. $info.PrivateBinPath += ';lib\net40'
  640. }
  641. else
  642. {
  643. $info.PrivateBinPath += ';lib\net45'
  644. }
  645. return $info
  646. }
  647. function New-DomainDispatcher($ToolsPath)
  648. {
  649. $utilityAssembly = [System.Reflection.Assembly]::LoadFrom((Join-Path $ToolsPath EntityFramework.PowerShell.Utility.dll))
  650. $dispatcher = $utilityAssembly.CreateInstance(
  651. 'System.Data.Entity.Migrations.Utilities.DomainDispatcher',
  652. $false,
  653. [System.Reflection.BindingFlags]::Instance -bor [System.Reflection.BindingFlags]::Public,
  654. $null,
  655. $PSCmdlet,
  656. $null,
  657. $null)
  658. return $dispatcher
  659. }
  660. function Remove-Runner($runner)
  661. {
  662. [AppDomain]::Unload($runner.Domain)
  663. }
  664. function Invoke-RunnerCommand($runner, $command, $parameters, $anonymousArguments)
  665. {
  666. $domain = $runner.Domain
  667. if ($anonymousArguments)
  668. {
  669. $anonymousArguments.GetEnumerator() | %{
  670. $domain.SetData($_.Name, $_.Value)
  671. }
  672. }
  673. $domain.CreateInstanceFrom(
  674. (Join-Path $runner.ToolsPath EntityFramework.PowerShell.dll),
  675. $command,
  676. $false,
  677. 0,
  678. $null,
  679. $parameters,
  680. $null,
  681. $null) | Out-Null
  682. }
  683. function Get-RunnerError($runner)
  684. {
  685. $domain = $runner.Domain
  686. if (!$domain.GetData('wasError'))
  687. {
  688. return $null
  689. }
  690. return @{
  691. Message = $domain.GetData('error.Message');
  692. TypeName = $domain.GetData('error.TypeName');
  693. StackTrace = $domain.GetData('error.StackTrace')
  694. }
  695. }
  696. function Get-MigrationsProject($name, $hideMessage)
  697. {
  698. if ($name)
  699. {
  700. return Get-SingleProject $name
  701. }
  702. $project = Get-Project
  703. $projectName = $project.Name
  704. if (!$hideMessage)
  705. {
  706. Write-Verbose "Using NuGet project '$projectName'."
  707. }
  708. return $project
  709. }
  710. function Get-MigrationsStartUpProject($name, $fallbackName)
  711. {
  712. $startUpProject = $null
  713. if ($name)
  714. {
  715. $startUpProject = Get-SingleProject $name
  716. }
  717. else
  718. {
  719. $startupProjectPaths = $DTE.Solution.SolutionBuild.StartupProjects
  720. if ($startupProjectPaths)
  721. {
  722. if ($startupProjectPaths.Length -eq 1)
  723. {
  724. $startupProjectPath = $startupProjectPaths[0]
  725. if (!(Split-Path -IsAbsolute $startupProjectPath))
  726. {
  727. $solutionPath = Split-Path $DTE.Solution.Properties.Item('Path').Value
  728. $startupProjectPath = Join-Path $solutionPath $startupProjectPath -Resolve
  729. }
  730. $startupProject = Get-SolutionProjects | ?{
  731. try
  732. {
  733. $fullName = $_.FullName
  734. }
  735. catch [NotImplementedException]
  736. {
  737. return $false
  738. }
  739. if ($fullName -and $fullName.EndsWith('\'))
  740. {
  741. $fullName = $fullName.Substring(0, $fullName.Length - 1)
  742. }
  743. return $fullName -eq $startupProjectPath
  744. }
  745. }
  746. else
  747. {
  748. Write-Verbose 'More than one start-up project found.'
  749. }
  750. }
  751. else
  752. {
  753. Write-Verbose 'No start-up project found.'
  754. }
  755. }
  756. if (!($startUpProject -and (Test-StartUpProject $startUpProject)))
  757. {
  758. $startUpProject = Get-MigrationsProject $fallbackName $true
  759. $startUpProjectName = $startUpProject.Name
  760. Write-Warning "Cannot determine a valid start-up project. Using project '$startUpProjectName' instead. Your configuration file and working directory may not be set as expected. Use the -StartUpProjectName parameter to set one explicitly. Use the -Verbose switch for more information."
  761. }
  762. else
  763. {
  764. $startUpProjectName = $startUpProject.Name
  765. Write-Verbose "Using StartUp project '$startUpProjectName'."
  766. }
  767. return $startUpProject
  768. }
  769. function Get-SolutionProjects()
  770. {
  771. $projects = New-Object System.Collections.Stack
  772. $DTE.Solution.Projects | %{
  773. $projects.Push($_)
  774. }
  775. while ($projects.Count -ne 0)
  776. {
  777. $project = $projects.Pop();
  778. # NOTE: This line is similar to doing a "yield return" in C#
  779. $project
  780. if ($project.ProjectItems)
  781. {
  782. $project.ProjectItems | ?{ $_.SubProject } | %{
  783. $projects.Push($_.SubProject)
  784. }
  785. }
  786. }
  787. }
  788. function Get-SingleProject($name)
  789. {
  790. $project = Get-Project $name
  791. if ($project -is [array])
  792. {
  793. throw "More than one project '$name' was found. Specify the full name of the one to use."
  794. }
  795. return $project
  796. }
  797. function Test-StartUpProject($project)
  798. {
  799. if ($project.Kind -eq '{cc5fd16d-436d-48ad-a40c-5a424c6e3e79}')
  800. {
  801. $projectName = $project.Name
  802. Write-Verbose "Cannot use start-up project '$projectName'. The Windows Azure Project type isn't supported."
  803. return $false
  804. }
  805. return $true
  806. }
  807. function Build-Project($project)
  808. {
  809. $configuration = $DTE.Solution.SolutionBuild.ActiveConfiguration.Name
  810. $DTE.Solution.SolutionBuild.BuildProject($configuration, $project.UniqueName, $true)
  811. if ($DTE.Solution.SolutionBuild.LastBuildInfo)
  812. {
  813. $projectName = $project.Name
  814. throw "The project '$projectName' failed to build."
  815. }
  816. }
  817. function Get-EntityFrameworkInstallPath($project)
  818. {
  819. $package = Get-Package -ProjectName $project.FullName | ?{ $_.Id -eq 'EntityFramework' }
  820. if (!$package)
  821. {
  822. $projectName = $project.Name
  823. throw "The EntityFramework package is not installed on project '$projectName'."
  824. }
  825. return Get-PackageInstallPath $package
  826. }
  827. function Get-PackageInstallPath($package)
  828. {
  829. $componentModel = Get-VsComponentModel
  830. $packageInstallerServices = $componentModel.GetService([NuGet.VisualStudio.IVsPackageInstallerServices])
  831. $vsPackage = $packageInstallerServices.GetInstalledPackages() | ?{ $_.Id -eq $package.Id -and $_.Version -eq $package.Version }
  832. return $vsPackage.InstallPath
  833. }
  834. function Check-Project($project)
  835. {
  836. if (!$project.FullName)
  837. {
  838. throw "The Project argument must refer to a Visual Studio project. Use the '`$project' variable provided by NuGet when running in install.ps1."
  839. }
  840. return $project.CodeModel
  841. }
  842. Export-ModuleMember @( 'Enable-Migrations', 'Add-Migration', 'Update-Database', 'Get-Migrations', 'Add-EFProvider', 'Add-EFDefaultConnectionFactory', 'Initialize-EFConfiguration') -Variable InitialDatabase
  843. # SIG # Begin signature block
  844. # MIIarwYJKoZIhvcNAQcCoIIaoDCCGpwCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
  845. # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
  846. # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQU3poUYDlTlwf2GyqxNJ7CRJO4
  847. # tk2gghWCMIIEwzCCA6ugAwIBAgITMwAAADPlJ4ajDkoqgAAAAAAAMzANBgkqhkiG
  848. # 9w0BAQUFADB3MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4G
  849. # A1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSEw
  850. # HwYDVQQDExhNaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EwHhcNMTMwMzI3MjAwODIz
  851. # WhcNMTQwNjI3MjAwODIzWjCBszELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hp
  852. # bmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jw
  853. # b3JhdGlvbjENMAsGA1UECxMETU9QUjEnMCUGA1UECxMebkNpcGhlciBEU0UgRVNO
  854. # OkY1MjgtMzc3Ny04QTc2MSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBT
  855. # ZXJ2aWNlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyt7KGQ8fllaC
  856. # X9hCMtQIbbadwMLtfDirWDOta4FQuIghCl2vly2QWsfDLrJM1GN0WP3fxYlU0AvM
  857. # /ZyEEXmsoyEibTPgrt4lQEWSTg1jCCuLN91PB2rcKs8QWo9XXZ09+hdjAsZwPrsi
  858. # 7Vux9zK65HG8ef/4y+lXP3R75vJ9fFdYL6zSDqjZiNlAHzoiQeIJJgKgzOUlzoxn
  859. # g99G+IVNw9pmHsdzfju0dhempaCgdFWo5WAYQWI4x2VGqwQWZlbq+abLQs9dVGQv
  860. # gfjPOAAPEGvhgy6NPkjsSVZK7Jpp9MsPEPsHNEpibAGNbscghMpc0WOZHo5d7A+l
  861. # Fkiqa94hLwIDAQABo4IBCTCCAQUwHQYDVR0OBBYEFABYGz7txfEGk74xPTa0rAtd
  862. # MvCBMB8GA1UdIwQYMBaAFCM0+NlSRnAK7UD7dvuzK7DDNbMPMFQGA1UdHwRNMEsw
  863. # SaBHoEWGQ2h0dHA6Ly9jcmwubWljcm9zb2Z0LmNvbS9wa2kvY3JsL3Byb2R1Y3Rz
  864. # L01pY3Jvc29mdFRpbWVTdGFtcFBDQS5jcmwwWAYIKwYBBQUHAQEETDBKMEgGCCsG
  865. # AQUFBzAChjxodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY3Jv
  866. # c29mdFRpbWVTdGFtcFBDQS5jcnQwEwYDVR0lBAwwCgYIKwYBBQUHAwgwDQYJKoZI
  867. # hvcNAQEFBQADggEBAAL/44wD6u9+OLm5fJ87UoOk+iM41AO4alm16uBviAP0b1Fq
  868. # lTp1hegc3AfFTp0bqM4kRxQkTzV3sZy8J3uPXU/8BouXl/kpm/dAHVKBjnZIA37y
  869. # mxe3rtlbIpFjOzJfNfvGkTzM7w6ZgD4GkTgTegxMvjPbv+2tQcZ8GyR8E9wK/EuK
  870. # IAUdCYmROQdOIU7ebHxwu6vxII74mHhg3IuUz2W+lpAPoJyE7Vy1fEGgYS29Q2dl
  871. # GiqC1KeKWfcy46PnxY2yIruSKNiwjFOPaEdHodgBsPFhFcQXoS3jOmxPb6897t4p
  872. # sETLw5JnugDOD44R79ECgjFJlJidUUh4rR3WQLYwggTsMIID1KADAgECAhMzAAAA
  873. # sBGvCovQO5/dAAEAAACwMA0GCSqGSIb3DQEBBQUAMHkxCzAJBgNVBAYTAlVTMRMw
  874. # EQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVN
  875. # aWNyb3NvZnQgQ29ycG9yYXRpb24xIzAhBgNVBAMTGk1pY3Jvc29mdCBDb2RlIFNp
  876. # Z25pbmcgUENBMB4XDTEzMDEyNDIyMzMzOVoXDTE0MDQyNDIyMzMzOVowgYMxCzAJ
  877. # BgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25k
  878. # MR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xDTALBgNVBAsTBE1PUFIx
  879. # HjAcBgNVBAMTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjCCASIwDQYJKoZIhvcNAQEB
  880. # BQADggEPADCCAQoCggEBAOivXKIgDfgofLwFe3+t7ut2rChTPzrbQH2zjjPmVz+l
  881. # URU0VKXPtIupP6g34S1Q7TUWTu9NetsTdoiwLPBZXKnr4dcpdeQbhSeb8/gtnkE2
  882. # KwtA+747urlcdZMWUkvKM8U3sPPrfqj1QRVcCGUdITfwLLoiCxCxEJ13IoWEfE+5
  883. # G5Cw9aP+i/QMmk6g9ckKIeKq4wE2R/0vgmqBA/WpNdyUV537S9QOgts4jxL+49Z6
  884. # dIhk4WLEJS4qrp0YHw4etsKvJLQOULzeHJNcSaZ5tbbbzvlweygBhLgqKc+/qQUF
  885. # 4eAPcU39rVwjgynrx8VKyOgnhNN+xkMLlQAFsU9lccUCAwEAAaOCAWAwggFcMBMG
  886. # A1UdJQQMMAoGCCsGAQUFBwMDMB0GA1UdDgQWBBRZcaZaM03amAeA/4Qevof5cjJB
  887. # 8jBRBgNVHREESjBIpEYwRDENMAsGA1UECxMETU9QUjEzMDEGA1UEBRMqMzE1OTUr
  888. # NGZhZjBiNzEtYWQzNy00YWEzLWE2NzEtNzZiYzA1MjM0NGFkMB8GA1UdIwQYMBaA
  889. # FMsR6MrStBZYAck3LjMWFrlMmgofMFYGA1UdHwRPME0wS6BJoEeGRWh0dHA6Ly9j
  890. # cmwubWljcm9zb2Z0LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY0NvZFNpZ1BDQV8w
  891. # OC0zMS0yMDEwLmNybDBaBggrBgEFBQcBAQROMEwwSgYIKwYBBQUHMAKGPmh0dHA6
  892. # Ly93d3cubWljcm9zb2Z0LmNvbS9wa2kvY2VydHMvTWljQ29kU2lnUENBXzA4LTMx
  893. # LTIwMTAuY3J0MA0GCSqGSIb3DQEBBQUAA4IBAQAx124qElczgdWdxuv5OtRETQie
  894. # 7l7falu3ec8CnLx2aJ6QoZwLw3+ijPFNupU5+w3g4Zv0XSQPG42IFTp8263Os8ls
  895. # ujksRX0kEVQmMA0N/0fqAwfl5GZdLHudHakQ+hywdPJPaWueqSSE2u2WoN9zpO9q
  896. # GqxLYp7xfMAUf0jNTbJE+fA8k21C2Oh85hegm2hoCSj5ApfvEQO6Z1Ktwemzc6bS
  897. # Y81K4j7k8079/6HguwITO10g3lU/o66QQDE4dSheBKlGbeb1enlAvR/N6EXVruJd
  898. # PvV1x+ZmY2DM1ZqEh40kMPfvNNBjHbFCZ0oOS786Du+2lTqnOOQlkgimiGaCMIIF
  899. # vDCCA6SgAwIBAgIKYTMmGgAAAAAAMTANBgkqhkiG9w0BAQUFADBfMRMwEQYKCZIm
  900. # iZPyLGQBGRYDY29tMRkwFwYKCZImiZPyLGQBGRYJbWljcm9zb2Z0MS0wKwYDVQQD
  901. # EyRNaWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMTAwODMx
  902. # MjIxOTMyWhcNMjAwODMxMjIyOTMyWjB5MQswCQYDVQQGEwJVUzETMBEGA1UECBMK
  903. # V2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0
  904. # IENvcnBvcmF0aW9uMSMwIQYDVQQDExpNaWNyb3NvZnQgQ29kZSBTaWduaW5nIFBD
  905. # QTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJyWVwZMGS/HZpgICBC
  906. # mXZTbD4b1m/My/Hqa/6XFhDg3zp0gxq3L6Ay7P/ewkJOI9VyANs1VwqJyq4gSfTw
  907. # aKxNS42lvXlLcZtHB9r9Jd+ddYjPqnNEf9eB2/O98jakyVxF3K+tPeAoaJcap6Vy
  908. # c1bxF5Tk/TWUcqDWdl8ed0WDhTgW0HNbBbpnUo2lsmkv2hkL/pJ0KeJ2L1TdFDBZ
  909. # +NKNYv3LyV9GMVC5JxPkQDDPcikQKCLHN049oDI9kM2hOAaFXE5WgigqBTK3S9dP
  910. # Y+fSLWLxRT3nrAgA9kahntFbjCZT6HqqSvJGzzc8OJ60d1ylF56NyxGPVjzBrAlf
  911. # A9MCAwEAAaOCAV4wggFaMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMsR6MrS
  912. # tBZYAck3LjMWFrlMmgofMAsGA1UdDwQEAwIBhjASBgkrBgEEAYI3FQEEBQIDAQAB
  913. # MCMGCSsGAQQBgjcVAgQWBBT90TFO0yaKleGYYDuoMW+mPLzYLTAZBgkrBgEEAYI3
  914. # FAIEDB4KAFMAdQBiAEMAQTAfBgNVHSMEGDAWgBQOrIJgQFYnl+UlE/wq4QpTlVnk
  915. # pDBQBgNVHR8ESTBHMEWgQ6BBhj9odHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtp
  916. # L2NybC9wcm9kdWN0cy9taWNyb3NvZnRyb290Y2VydC5jcmwwVAYIKwYBBQUHAQEE
  917. # SDBGMEQGCCsGAQUFBzAChjhodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpL2Nl
  918. # cnRzL01pY3Jvc29mdFJvb3RDZXJ0LmNydDANBgkqhkiG9w0BAQUFAAOCAgEAWTk+
  919. # fyZGr+tvQLEytWrrDi9uqEn361917Uw7LddDrQv+y+ktMaMjzHxQmIAhXaw9L0y6
  920. # oqhWnONwu7i0+Hm1SXL3PupBf8rhDBdpy6WcIC36C1DEVs0t40rSvHDnqA2iA6VW
  921. # 4LiKS1fylUKc8fPv7uOGHzQ8uFaa8FMjhSqkghyT4pQHHfLiTviMocroE6WRTsgb
  922. # 0o9ylSpxbZsa+BzwU9ZnzCL/XB3Nooy9J7J5Y1ZEolHN+emjWFbdmwJFRC9f9Nqu
  923. # 1IIybvyklRPk62nnqaIsvsgrEA5ljpnb9aL6EiYJZTiU8XofSrvR4Vbo0HiWGFzJ
  924. # NRZf3ZMdSY4tvq00RBzuEBUaAF3dNVshzpjHCe6FDoxPbQ4TTj18KUicctHzbMrB
  925. # 7HCjV5JXfZSNoBtIA1r3z6NnCnSlNu0tLxfI5nI3EvRvsTxngvlSso0zFmUeDord
  926. # EN5k9G/ORtTTF+l5xAS00/ss3x+KnqwK+xMnQK3k+eGpf0a7B2BHZWBATrBC7E7t
  927. # s3Z52Ao0CW0cgDEf4g5U3eWh++VHEK1kmP9QFi58vwUheuKVQSdpw5OPlcmN2Jsh
  928. # rg1cnPCiroZogwxqLbt2awAdlq3yFnv2FoMkuYjPaqhHMS+a3ONxPdcAfmJH0c6I
  929. # ybgY+g5yjcGjPa8CQGr/aZuW4hCoELQ3UAjWwz0wggYHMIID76ADAgECAgphFmg0
  930. # AAAAAAAcMA0GCSqGSIb3DQEBBQUAMF8xEzARBgoJkiaJk/IsZAEZFgNjb20xGTAX
  931. # BgoJkiaJk/IsZAEZFgltaWNyb3NvZnQxLTArBgNVBAMTJE1pY3Jvc29mdCBSb290
  932. # IENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0wNzA0MDMxMjUzMDlaFw0yMTA0MDMx
  933. # MzAzMDlaMHcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYD
  934. # VQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xITAf
  935. # BgNVBAMTGE1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQTCCASIwDQYJKoZIhvcNAQEB
  936. # BQADggEPADCCAQoCggEBAJ+hbLHf20iSKnxrLhnhveLjxZlRI1Ctzt0YTiQP7tGn
  937. # 0UytdDAgEesH1VSVFUmUG0KSrphcMCbaAGvoe73siQcP9w4EmPCJzB/LMySHnfL0
  938. # Zxws/HvniB3q506jocEjU8qN+kXPCdBer9CwQgSi+aZsk2fXKNxGU7CG0OUoRi4n
  939. # rIZPVVIM5AMs+2qQkDBuh/NZMJ36ftaXs+ghl3740hPzCLdTbVK0RZCfSABKR2YR
  940. # JylmqJfk0waBSqL5hKcRRxQJgp+E7VV4/gGaHVAIhQAQMEbtt94jRrvELVSfrx54
  941. # QTF3zJvfO4OToWECtR0Nsfz3m7IBziJLVP/5BcPCIAsCAwEAAaOCAaswggGnMA8G
  942. # A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFCM0+NlSRnAK7UD7dvuzK7DDNbMPMAsG
  943. # A1UdDwQEAwIBhjAQBgkrBgEEAYI3FQEEAwIBADCBmAYDVR0jBIGQMIGNgBQOrIJg
  944. # QFYnl+UlE/wq4QpTlVnkpKFjpGEwXzETMBEGCgmSJomT8ixkARkWA2NvbTEZMBcG
  945. # CgmSJomT8ixkARkWCW1pY3Jvc29mdDEtMCsGA1UEAxMkTWljcm9zb2Z0IFJvb3Qg
  946. # Q2VydGlmaWNhdGUgQXV0aG9yaXR5ghB5rRahSqClrUxzWPQHEy5lMFAGA1UdHwRJ
  947. # MEcwRaBDoEGGP2h0dHA6Ly9jcmwubWljcm9zb2Z0LmNvbS9wa2kvY3JsL3Byb2R1
  948. # Y3RzL21pY3Jvc29mdHJvb3RjZXJ0LmNybDBUBggrBgEFBQcBAQRIMEYwRAYIKwYB
  949. # BQUHMAKGOGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2kvY2VydHMvTWljcm9z
  950. # b2Z0Um9vdENlcnQuY3J0MBMGA1UdJQQMMAoGCCsGAQUFBwMIMA0GCSqGSIb3DQEB
  951. # BQUAA4ICAQAQl4rDXANENt3ptK132855UU0BsS50cVttDBOrzr57j7gu1BKijG1i
  952. # uFcCy04gE1CZ3XpA4le7r1iaHOEdAYasu3jyi9DsOwHu4r6PCgXIjUji8FMV3U+r
  953. # kuTnjWrVgMHmlPIGL4UD6ZEqJCJw+/b85HiZLg33B+JwvBhOnY5rCnKVuKE5nGct
  954. # xVEO6mJcPxaYiyA/4gcaMvnMMUp2MT0rcgvI6nA9/4UKE9/CCmGO8Ne4F+tOi3/F
  955. # NSteo7/rvH0LQnvUU3Ih7jDKu3hlXFsBFwoUDtLaFJj1PLlmWLMtL+f5hYbMUVbo
  956. # nXCUbKw5TNT2eb+qGHpiKe+imyk0BncaYsk9Hm0fgvALxyy7z0Oz5fnsfbXjpKh0
  957. # NbhOxXEjEiZ2CzxSjHFaRkMUvLOzsE1nyJ9C/4B5IYCeFTBm6EISXhrIniIh0EPp
  958. # K+m79EjMLNTYMoBMJipIJF9a6lbvpt6Znco6b72BJ3QGEe52Ib+bgsEnVLaxaj2J
  959. # oXZhtG6hE6a/qkfwEm/9ijJssv7fUciMI8lmvZ0dhxJkAj0tr1mPuOQh5bWwymO0
  960. # eFQF1EEuUKyUsKV4q7OglnUa2ZKHE3UiLzKoCG6gW4wlv6DvhMoh1useT8ma7kng
  961. # 9wFlb4kLfchpyOZu6qeXzjEp/w7FW1zYTRuh2Povnj8uVRZryROj/TGCBJcwggST
  962. # AgEBMIGQMHkxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYD
  963. # VQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xIzAh
  964. # BgNVBAMTGk1pY3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBAhMzAAAAsBGvCovQO5/d
  965. # AAEAAACwMAkGBSsOAwIaBQCggbAwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQw
  966. # HAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwIwYJKoZIhvcNAQkEMRYEFFEE
  967. # zHuXOuYUdMMU6ccXv39TiFxTMFAGCisGAQQBgjcCAQwxQjBAoCKAIABFAG4AdABp
  968. # AHQAeQAgAEYAcgBhAG0AZQB3AG8AcgBroRqAGGh0dHA6Ly9tc2RuLmNvbS9kYXRh
  969. # L2VmIDANBgkqhkiG9w0BAQEFAASCAQBgQHCc01/cBLBTTzbmZi2C1McvIzYz9F4d
  970. # fvAc+d7VdsyfUcSRdl96k297wjgKtT8aS5ENWXs/NaZAIB1gBTu9nqzx3r8Rp7Pn
  971. # qr3Aosj7bahFVcjR9+UIgPqPtgQVQFU3eUxFcgXIyYz5Q7JZc2IY9kX7jj3Ma8uI
  972. # tO5VG45PYaDc5jjmZs1a8CYCUtdgZys+dtNSSw6mqpFZY80Be5s/+RVYd9sYu1sY
  973. # 1/Sh1sIsuqJwbqMJy96ZwvY11EgqwjX2pgm9wQ9DjFNl2PqZXiY1xTCko7uA4YvR
  974. # SysBXKEzByYev9KAbFV/wmZdhuyazTtrBuwflPKsxn1aVg1xtcFpoYICKDCCAiQG
  975. # CSqGSIb3DQEJBjGCAhUwggIRAgEBMIGOMHcxCzAJBgNVBAYTAlVTMRMwEQYDVQQI
  976. # EwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3Nv
  977. # ZnQgQ29ycG9yYXRpb24xITAfBgNVBAMTGE1pY3Jvc29mdCBUaW1lLVN0YW1wIFBD
  978. # QQITMwAAADPlJ4ajDkoqgAAAAAAAMzAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkD
  979. # MQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMTQwMjI1MDkzMTQ0WjAjBgkq
  980. # hkiG9w0BCQQxFgQUXYYIPCdzaJx5E5wlK51Y/RoP9dowDQYJKoZIhvcNAQEFBQAE
  981. # ggEAkc2/P/rVvbGweFkA/ZaVqvKSdGn2Kc8q8dIrfQbnRjEGMrYSJvht2bjXnQHZ
  982. # cxyqyVRpHtWkGlYKnzZvmxuxC30TJ3MLOlDDmJok5QfrZe01NSXOZ1lWRg15dF6I
  983. # hFhpsAPLL+PFYUMrIWWvR/5qZ8m4+tqfY4lmxriDlQYve2PQv0YUh9Fx7frQxhSj
  984. # qAC0BPVNoSOsv5i182IZr5lqZh4Aae2DhTBjbHzT3Ibf1RiRI0p8/3Mz+RVby4Xv
  985. # WbdNDNkQMAefo37yVaDQHHR4n6ooAtU4WeRJX1/awlMwWViguzG2GVgKN7+1r3hL
  986. # 6EHKk+w0L9lxR2hthCkBn8+rCw==
  987. # SIG # End signature block