Rick's Dev Notes

Version 0.3.3

Dev notes you can use

Last updated on Sat, 17 Jun 2023 21:26 UTC

Database

EF Migrations

The migration tool has to be able to build the DbContext to know what’s in it.

dotnet add package Microsoft.EntityFrameworkCore.Design

Add a new migration

param(
    [Parameter(Mandatory=$true)]
    [string] $MigrationName
)

dotnet ef migrations add --startup-project ../App.Api/ --context AppContext $MigrationName

Update database

param(
    [string] $TargetMigration
)

# TODO print names of last 5 migrations to allow user to input
if ([string]::IsNullOrEmpty($TargetMigration)) {
    dotnet ef database update --startup-project ../App.Api/ --context AppContext
}
else {
    dotnet ef database update --startup-project ../App.Api/ --context AppContext $TargetMigration
}

DB Backup

PowerShell script for automating the creation of new databases in a local environment setting.

#Requires -RunAsAdministrator

# If SqlServer module isn't installed
if (!(Get-module SqlServer))
{
	Write-Host "Installing SqlServer module..."
	Install-Module SqlServer
}

Write-Host "Loading SqlServer module..."
Import-Module SqlServer

$localServer = "(localdb)\MSSQLLocalDB"

Write-Host "Select database to copy:"
$database = Get-SqlDatabase -ServerInstance $localServer | Where-Object { $_.Owner -ne "sa" } | Out-GridView -Title "Select database to copy" -PassThru

if ($database -eq $null)
{
	Write-Error "A database was not selected."
	exit 1;
}

$databaseName = $database.Name

$newDatabaseName  = Read-Host -Prompt "Enter name of new database [${databaseName}_Copy]"
if (-not [bool]$newDatabaseName) { $newDatabaseName = "${databaseName}_Copy" }

# Check if name already exists
Get-SqlDatabase -ServerInstance $localServer | ForEach-Object -Process {
	if ($_.Name -eq $newDatabaseName)
	{
		Write-Error "Database $newDatabaseName already exists."
		exit 1;
	}
}

Write-Host "Creating $newDatabaseName on $localServer..."
$server = New-Object Microsoft.SqlServer.Management.Smo.Server($localServer)
$newDatabase = New-Object Microsoft.SqlServer.Management.Smo.Database($server, $newDatabaseName)
$newDatabase.Create()

Write-Host "Backing up $databaseName to ${HOME}\${databaseName}.bak..."
if (Test-Path "${HOME}\${databaseName}.bak" -PathType Leaf)
{
	Rename-Item -Path "${HOME}\${databaseName}.bak" -NewName "${databaseName}.old.bak"
}
Backup-SqlDatabase -ServerInstance $localServer -Database $databaseName -BackupFile "${HOME}\${databaseName}.bak"
if ((Test-Path "${HOME}\${databaseName}.bak" -PathType Leaf) -and (Test-Path "${HOME}\${databaseName}.old.bak" -PathType Leaf))
{
	Remove-Item -Path "${HOME}\${databaseName}.old.bak"
}

# Read backup file to get logical names of .mdf and .ldf
Write-Host "Parsing data in ${databaseName}.bak..."
$restoreObject = New-Object Microsoft.SqlServer.Management.Smo.Restore
$backupDeviceItem = New-Object Microsoft.SqlServer.Management.Smo.BackupDeviceItem("${HOME}\${databaseName}.bak", 'File')
$restoreObject.Devices.Add($backupDeviceItem)
$fileList = $restoreObject.ReadFileList($server)
$mdfLogicalName = $fileList.select("Type = 'D'")[0].LogicalName
$ldfLogicalName = $fileList.select("Type = 'L'")[0].LogicalName

# Set new file locations and restore to new DB
Write-Host "Assigning data relocation for ${newDatabaseName}..."
$RelocateData = New-Object Microsoft.SqlServer.Management.Smo.RelocateFile("$mdfLogicalName", "${HOME}\${newDatabaseName}.mdf")
$RelocateLog = New-Object Microsoft.SqlServer.Management.Smo.RelocateFile("$ldfLogicalName", "${HOME}\${newDatabaseName}_log.ldf")
Write-Host "Restoring data to $newDatabaseName on $localServer..."
Restore-SqlDatabase -ReplaceDatabase -ServerInstance $localServer -Database $newDatabaseName -BackupFile "${HOME}\${databaseName}.bak" -RelocateFile @($RelocateData,$RelocateLog)

Write-Host "Updating connection strings to ${newDatabaseName}..."
& $PSScriptRoot\switch-environment.ps1 -Database $newDatabaseName

Conn String Updater

PowerShell script to change what environment your connection string points to.

param (
	[string]$Environment,
	[string]$Database
)

if ($Environment.Length -gt 0 -and $Environment -ne "Development" -and $Database.Length -gt 0)
{
	Write-Host "You can only set a database on the Development environment"
	return
}

if ($Database.Length -gt 0)
{
	$Environment = "Development"
}

if ($Environment.Length -eq 0)
{
	Write-Host "0) Development"
	Write-Host "1) Sandbox"
	Write-Host "2) Playground"
	Write-Host "3) Treehouse"
	Write-Host "4) Park"
	Write-Host "5) Alpha"
	Write-Host "6) Beta"
	$selectedEnvironment = Read-Host -Prompt "Select environment [Development]"
	Switch ($selectedEnvironment)
	{
		1 { $Environment = "sandbox" }
		2 { $Environment = "playground" }
		3 { $Environment = "treehouse" }
		4 { $Environment = "park" }
		5 { $Environment = "alpha" }
		6 { $Environment = "beta" }
		Default { $Environment = "Development" }
	}

	if ($Environment -eq "Development")
	{
		$Database = Read-Host -Prompt "Enter name of database [App]"
	}
}

$appsettings = Get-Content $PSScriptRoot\App.Api\appsettings.local.json -raw | ConvertFrom-Json
$newAppsettings = Get-Content $PSScriptRoot\App.Api\appsettings.$Environment.json -raw | ConvertFrom-Json
$appsettings.ConnectionStrings.AppDbContext = $newAppsettings.ConnectionStrings.AppDbContext

if ($Database.Length -gt 0)
{
	$appsettings.ConnectionStrings.AppDbContext = $appsettings.ConnectionStrings.AppDbContext.replace("Initial Catalog=App;", "Initial Catalog=${Database};")
}

$appsettings | ConvertTo-Json -depth 32 | Set-Content $PSScriptRoot\App.Api\appsettings.local.json

Set up new local Dev DB

You need both SQL Server and SSMS Be sure to set the login as “Mixed” and create a password for the “sa” account. Login with sa account Create the DB by right clicking the server and hitting create new database. All default is fine. Create the dev user like below:

-- Creates the login AbolrousHazem with password '340$Uuxwp7Mcxo7Khy'.  
CREATE LOGIN AbolrousHazem   
    WITH PASSWORD = '340$Uuxwp7Mcxo7Khy';  
GO  

-- Creates a database user for the login created above.  
CREATE USER AbolrousHazem FOR LOGIN AbolrousHazem;  
GO

Right click the DB and hit properties. Verify the new user has connect permission granted to the new database. Good to go. Go run your migration.